欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TextView富文本学习五 - 设置了SpannableString后设置了maxLines,ellipsize=end失效

程序员文章站 2024-02-04 13:53:46
...

TextView设置了ClickableSpan并设置了maxLines,ellipsize="end"后内容可滑动的问题已经解决了,但ellipsize=”end”并没有效果,三行结束的位置并没有出现…

*有关于这个问题的讨论:

https://*.com/questions/14691511/textview-using-spannable-ellipsize-doesnt-work
摘抄其中一种解决方案:

public class EllipsizeTextView extends android.support.v7.widget.AppCompatTextView {
    private static final String THREE_DOTS = "...";
    private static final int THREE_DOTS_LENGTH = THREE_DOTS.length();

    private volatile boolean enableEllipsizeWorkaround = true;
    private SpannableStringBuilder spannableStringBuilder;

    public EllipsizeTextView(Context context) {
        super(context);
    }

    public EllipsizeTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public EllipsizeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    public void setEnableEllipsizeWorkaround(boolean enableEllipsizeWorkaround) {
        this.enableEllipsizeWorkaround = enableEllipsizeWorkaround;
    }

    // https://*.com/questions/14691511/textview-using-spannable-ellipsize-doesnt-work
    // https://blog.csdn.net/htyxz8802/article/details/50387950
    @Override
    protected void onDraw(Canvas canvas) {
        if (enableEllipsizeWorkaround && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ) {
            final Layout layout = getLayout();
            if (layout.getLineCount() >= getMaxLines()) {
                CharSequence charSequence = getText();

                int lastCharDown = layout.getLineVisibleEnd(getMaxLines()-1);

                if (lastCharDown >= THREE_DOTS_LENGTH && charSequence.length() > lastCharDown) {
                    if (spannableStringBuilder == null) {
                        spannableStringBuilder = new SpannableStringBuilder();
                    } else {
                        spannableStringBuilder.clear();
                    }

                    if (charSequence instanceof String){
                        String tempCharSequ = ((String)charSequence).substring(0, lastCharDown);
                        if ((tempCharSequ).contains("\n")){
                            spannableStringBuilder.append(charSequence.subSequence(0, lastCharDown));
                        }else {
                            spannableStringBuilder.append(charSequence.subSequence(0, lastCharDown - THREE_DOTS_LENGTH)).append(THREE_DOTS);
                        }
                    }else{
                        String tempCharSequ = charSequence.toString().substring(0, lastCharDown);
                        if ((tempCharSequ).contains("\n")){
                            spannableStringBuilder.append(charSequence.subSequence(0, lastCharDown));
                        }else {
                            spannableStringBuilder.append(charSequence.subSequence(0, lastCharDown - THREE_DOTS_LENGTH)).append(THREE_DOTS);
                        }
                    }

                    setText(spannableStringBuilder);
                }
            }
        }

        super.onDraw(canvas);
    }
}

** 注意 一:给TextView设置Span时的模式必须为Spannable.SPAN_EXCLUSIVE_EXCLUSIVE,否则在RecyclerView等列表中,如果暂存了生成的SpannableString,再次使用缓存值时可能会应用前面的模式,导致span失效。
ForegroundColorSpan span = new ForegroundColorSpan(mContext.getResources().getColor(R.color.mushroom_community_slider_selected_bg));
spannable.setSpan(span, start, start + tagNameMatch.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);**

注意 二:这种方法也能够解决设置了SpannableString后文本滑动问题,因为在TextView中对文本进行了截取,不会超过最大行,有个需要注意的问题是要处理文本中的换行\n,特别是开头,结尾,最大行内部的换行\n,最简单的办法是在列表页把所有的\n去掉,或者多个连续\n只保留一个。