Android - Expandable TextView with Animation

后端 未结 15 1107
小蘑菇
小蘑菇 2020-11-28 18:24

I have a TextView which firstly shows a small portion of a long text.

The user can press a \"see more\" button to expand the TextView and s

15条回答
  •  天涯浪人
    2020-11-28 19:01

    If you want to do it based on the number of lines, here's a way to do it:

    (Gist of full code)

    /**
     * Ellipsize the text when the lines of text exceeds the value provided by {@link #makeExpandable} methods.
     * Appends {@link #MORE} or {@link #LESS} as needed.
     * TODO: add animation
     * Created by vedant on 3/10/15.
     */
    public class ExpandableTextView extends TextView {
        private static final String TAG = "ExpandableTextView";
        private static final String ELLIPSIZE = "... ";
        private static final String MORE = "more";
        private static final String LESS = "less";
    
        private String mFullText;
        private int mMaxLines;
    
        //...constructors...
    
        public void makeExpandable(String fullText, int maxLines) {
            mFullText =fullText;
            mMaxLines = maxLines;
            ViewTreeObserver vto = getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    ViewTreeObserver obs = getViewTreeObserver();
                    obs.removeOnGlobalLayoutListener(this);
                    if (getLineCount() <= maxLines) {
                        setText(mFullText);
                    } else {
                        setMovementMethod(LinkMovementMethod.getInstance());
                        showLess();
                    }
                }
            });
        }
    
        /**
         * truncate text and append a clickable {@link #MORE}
         */
        private void showLess() {
            int lineEndIndex = getLayout().getLineEnd(mMaxLines - 1);
            String newText = mFullText.substring(0, lineEndIndex - (ELLIPSIZE.length() + MORE.length() + 1))
                    + ELLIPSIZE + MORE;
            SpannableStringBuilder builder = new SpannableStringBuilder(newText);
            builder.setSpan(new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    showMore();
                }
            }, newText.length() - MORE.length(), newText.length(), 0);
            setText(builder, BufferType.SPANNABLE);
        }
    
        /**
         * show full text and append a clickable {@link #LESS}
         */
        private void showMore() {
            // create a text like subText + ELLIPSIZE + MORE
            SpannableStringBuilder builder = new SpannableStringBuilder(mFullText + LESS);
            builder.setSpan(new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    showLess();
                }
            }, builder.length() - LESS.length(), builder.length(), 0);
            setText(builder, BufferType.SPANNABLE);
        }
    }
    

提交回复
热议问题