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

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

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

https://stackoverflow.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://stackoverflow.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只保留一个。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值