Set Text View ellipsize and add view more at end

前端 未结 13 1170

I am trying to set ellipsize of text view. using the following code. I want to add \"view more\" at the end of truncated string after 3 dots. If this would be possible with

相关标签:
13条回答
  • 2020-12-02 13:06

    In Kotlin adapter you can write like this to "View More" on TextView

    if (News[position].description.length > 150) {
      holder.desc.text = Html.fromHtml(News[position].description.substring(0, 150) + "..." + "<font color='blue'> <u>View More</u></font>")
    } else {
       holder.desc.text = News[position].description
    }
    holder.desc.setOnClickListener {
       if (holder.desc.text.toString().endsWith("View More")) {
          holder.desc.text = News[position].description
       } else {
          if (News[position].description.length > 150) {
            holder.desc.text = Html.fromHtml(News[position].description.substring(0, 150) + "..." + "<font color='blue'> <u>View More</u></font>")
          } else holder.desc.text = News[position].description
       }
    }
    
    0 讨论(0)
  • 2020-12-02 13:07

    This solution is a bit easier to implement in code. It doesn't support on-the-fly changes well, but can easily be modified to do so.

    public class ExpandableTextView extends TextView {
    
        private final String readMoreText = "...read more";
        private final int readMoreColor = Color.parseColor("#4A0281");
    
        private int _maxLines = 4;
        private CharSequence originalText;
    
        public ExpandableTextView(Context context) {
            super(context);
            init(context);
        }
    
        public ExpandableTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context);
        }
    
        private void init(Context context) {
    
            ViewTreeObserver vto = getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
    
                    ViewTreeObserver obs = getViewTreeObserver();
                    obs.removeGlobalOnLayoutListener(this);
    
                    truncateText();
                }
            });
        }
    
        @Override
        public void setText(CharSequence text, BufferType type) {
            super.setText(text, type);
    
            if (originalText == null) {
                originalText = text;
            }
        }
    
        @Override
        public int getMaxLines() {
            return _maxLines;
        }
    
        @Override
        public void setMaxLines(int maxLines) {
            _maxLines = maxLines;
        }
    
        public void truncateText() {
    
            int maxLines = _maxLines;
            String text = getText().toString();
    
            if (getLineCount() >= maxLines) {
    
                int lineEndIndex = getLayout().getLineEnd(maxLines - 1);
    
                String truncatedText = getText().subSequence(0, lineEndIndex - readMoreText.length() + 1) + readMoreText;
    
                Spannable spannable = new SpannableString(truncatedText);
                spannable.setSpan(new ForegroundColorSpan(readMoreColor), truncatedText.length() - readMoreText.length(), truncatedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
                setText(spannable, TextView.BufferType.SPANNABLE);
    
                super.setMaxLines(_maxLines);
            }
        }
    
        public void expandText() {
            setText(originalText);
            super.setMaxLines(1000);
        }
    
        public void reset() {
            originalText = null;
        }
    }
    
    0 讨论(0)
  • 2020-12-02 13:08

    You can use below code for this;

     holder.tvMoreInfo.setText(horizontalList.get(position));
    
            holder.tvMoreInfo.post(new Runnable() {
                @Override
                public void run() {
                    int lineCount = holder.tvMoreInfo.getLineCount();
                    if (lineCount<3)
                    {
    
                    }else
                    {
                        makeTextViewResizable(holder.tvMoreInfo, 3, "...More", true);
                    }
                }
            });
    
    
    
     public static void makeTextViewResizable(final TextView tv, final int maxLine, final String expandText, final boolean viewMore) {
    
        if (tv.getTag() == null) {
            tv.setTag(tv.getText());
        }
        ViewTreeObserver vto = tv.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    
            @SuppressWarnings("deprecation")
            @Override
            public void onGlobalLayout() {
                String text;
                int lineEndIndex;
                ViewTreeObserver obs = tv.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
                if (maxLine == 0) {
                    lineEndIndex = tv.getLayout().getLineEnd(0);
                    text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
                } else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
                    lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
                    text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
                } else {
                    lineEndIndex = tv.getLayout().getLineEnd(tv.getLayout().getLineCount() - 1);
                    text = tv.getText().subSequence(0, lineEndIndex) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
                }
                tv.setText(Html.fromHtml(text));
                tv.setMovementMethod(LinkMovementMethod.getInstance());
    
                tv.setText(
                        addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, lineEndIndex, expandText,
                                viewMore), TextView.BufferType.SPANNABLE);
            }
        });
    }
    
    private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
                                                                            final int maxLine, final String spanableText, final boolean viewMore) {
        String str = strSpanned.toString();
        SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);
    
        if (str.contains(spanableText)) {
            ssb.setSpan(new MySpannable(false) {
    
                @Override
                public void onClick(View widget) {
                    tv.setLayoutParams(tv.getLayoutParams());
                    tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                    tv.invalidate();
                    if (viewMore) {
                        makeTextViewResizable(tv, -1, "...Less", false);
                    } else {
                        makeTextViewResizable(tv, 3, "...More", true);
                    }
    
                }
            }, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);
    
        }
        return ssb;
    
    }
    
    0 讨论(0)
  • 2020-12-02 13:12

    Find my answer

       public static void makeTextViewResizable(final TextView tv, final int maxLine, final String expandText, final boolean viewMore) {
    
        if (tv.getTag() == null) {
            tv.setTag(tv.getText());
        }
        ViewTreeObserver vto = tv.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    
            @SuppressWarnings("deprecation")
            @Override
            public void onGlobalLayout() {
    
                ViewTreeObserver obs = tv.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
                if (maxLine == 0) {
                    int lineEndIndex = tv.getLayout().getLineEnd(0);
                    String text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
                    tv.setText(text);
                    tv.setMovementMethod(LinkMovementMethod.getInstance());
                    tv.setText(
                            addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, maxLine, expandText,
                                    viewMore), TextView.BufferType.SPANNABLE);
                } else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
                    int lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
                    String text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
                    tv.setText(text);
                    tv.setMovementMethod(LinkMovementMethod.getInstance());
                    tv.setText(
                            addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, maxLine, expandText,
                                    viewMore), TextView.BufferType.SPANNABLE);
                } else {
                    int lineEndIndex = tv.getLayout().getLineEnd(tv.getLayout().getLineCount() - 1);
                    String text = tv.getText().subSequence(0, lineEndIndex) + " " + expandText;
                    tv.setText(text);
                    tv.setMovementMethod(LinkMovementMethod.getInstance());
                    tv.setText(
                            addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, lineEndIndex, expandText,
                                    viewMore), TextView.BufferType.SPANNABLE);
                }
            }
        });
    
    }
    
    private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
                                                                            final int maxLine, final String spanableText, final boolean viewMore) {
        String str = strSpanned.toString();
        SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);
    
        if (str.contains(spanableText)) {
    
    
            ssb.setSpan(new MySpannable(false){
                @Override
                public void onClick(View widget) {
                    if (viewMore) {
                        tv.setLayoutParams(tv.getLayoutParams());
                        tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                        tv.invalidate();
                        makeTextViewResizable(tv, -1, "See Less", false);
                    } else {
                        tv.setLayoutParams(tv.getLayoutParams());
                        tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                        tv.invalidate();
                        makeTextViewResizable(tv, 3, ".. See More", true);
                    }
                }
            }, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);
    
        }
        return ssb;
    
    }
    

    Another class:-

    import android.graphics.Color;
    import android.text.TextPaint;
    import android.text.style.ClickableSpan;
    import android.view.View;
    
    public class MySpannable extends ClickableSpan {
    
    private boolean isUnderline = true;
    
    /**
     * Constructor
     */
    public MySpannable(boolean isUnderline) {
        this.isUnderline = isUnderline;
    }
    
    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(isUnderline);
        ds.setColor(Color.parseColor("#1b76d3"));
    }
    
    @Override
    public void onClick(View widget) {
    
    
     }
    }
    

    Last step to call it:

    DetailTv.setText(discription);
    makeTextViewResizable(DetailTv, 3, "See More", true);
    
    0 讨论(0)
  • 2020-12-02 13:13

    Instead of using android:layout_alignParentLeft="true" in first textview use android:layout_toLeftOf="@+id/textView1"

    This should take care of the overlapping text

    0 讨论(0)
  • 2020-12-02 13:15

    Thanks to Jitender's answer.Improving on it I have done the below implementation based on length of text.This might not be ideal solution if you want View More option exactly after specified number of lines but assuming that there are around 50 characters in single line the solution will work well if you are adjustable with number of lines.Below solution will add View More option if text length is greater than 150 and will ellipsize the text to 150 characters.On clicking on View More it will show complete text with Show Less option and on clicking on Show Less again it will ellipsize the text to 150 characters.No separate view is required.Also it works well with recyclerview item's textview.

    if(inputText.length()>150)
            {
                String text=inputText.substring(0,150)+"...";
                final String fulltext=inputText;
    
                final SpannableString ss = new SpannableString(text+"View More");
    
                ClickableSpan span1 = new ClickableSpan() {
                    @Override
                    public void onClick(View textView) {
                        // do some thing
                        SpannableString ss1 = new SpannableString(fulltext+"Show Less");
                        ClickableSpan span2 = new ClickableSpan() {
                            @Override
                            public void onClick(View textView) {
                                // do some thing
                                textView.setText(ss);
                                textView.setMovementMethod(LinkMovementMethod.getInstance());
    
                            }
                        };
                        ss1.setSpan(span2, fulltext.length(), ss1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        ss1.setSpan(new ForegroundColorSpan(Color.BLUE), fulltext.length(), ss1.length(),
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    
                        textView.setText(ss1);
                        textView.setMovementMethod(LinkMovementMethod.getInstance());
                    }
                };
                ss.setSpan(span1, 153, 162, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                ss.setSpan(new ForegroundColorSpan(Color.BLUE), 153,162,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
                textView.setText(ss);
                textView.setMovementMethod(LinkMovementMethod.getInstance());
            }
    else
            {
                textView.setText(inputText);
            }
    
    0 讨论(0)
提交回复
热议问题