美文网首页
Android分段可点击TextView

Android分段可点击TextView

作者: 沉默的菋道 | 来源:发表于2019-06-27 16:30 被阅读0次
分段可点击的TextView

这是之前做直播项目的一个功能,需要实现图片文字混排,并且需要识别出用户名可点击跳转,为了避免页面过深造成一些性能上维护上的问题,于是想到android里的Span来实现这个功能,代码如下,注释很详细就不细说了。

public class SpanTextView extends TextView {
    private List<BaseSpanModel> spanModels;
    private SpanClickListener listener;

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

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

    public SpanTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    // 设置文本内容
    public void setText(List<BaseSpanModel> spanModels, SpanClickListener listener) {
        this.spanModels = spanModels;
        this.listener = listener;
        this.setClickable(true);
        this.setMovementMethod(LinkMovementMethod.getInstance());
        //循环取出文本对象
        for (int i = 0; i < spanModels.size(); i++) {
            BaseSpanModel baseSpanModel = spanModels.get(i);
            SpannableString spannableString;
            if (baseSpanModel instanceof ClickSpanModel) {
                spannableString = getClickableSpan(i, (ClickSpanModel) baseSpanModel);
            } else {
                spannableString = new SpannableString(baseSpanModel.getContent());
            }
            //  设置或追加文本内容
            if (i == 0) {
                this.setText(spannableString);
            } else {
                this.append(spannableString);
            }
        }
    }

    private SpannableString getClickableSpan(int position, ClickSpanModel spanModel) {
        SpannableString spannableString = new SpannableString(spanModel.getContent());
        int start = 0;
        int end = spannableString.length();
        //这一行是实现局部点击效果,实现Clickable(自定义的继承ClickableSpan implements OnClickListener)
        spannableString.setSpan(new MyClickableSpan(position), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //这一行是设置文字颜色的
        spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#fa668e")), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        //这一行主要是用来消除点击文字下划线的
        spannableString.setSpan(new NoUnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

    class MyClickableSpan extends ClickableSpan implements View.OnClickListener {
        private int position;

        public MyClickableSpan(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            if (listener != null) {
                listener.OnClickListener(position);
            }
            //为了取消点击View效果(某些情况失效)
            setText(spanModels, listener);
        }
    }

    public class NoUnderlineSpan extends UnderlineSpan {
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    }

    public interface SpanClickListener {
        void OnClickListener(int position);
    }

    public static class BaseSpanModel {

        private String content;

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }

    public static class ClickSpanModel extends BaseSpanModel {
        private int id;

        public ClickSpanModel() {
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }
    }

    public static class TextSpanModel extends BaseSpanModel {
    }
}

组装要显示的文字段落,这里我将响应点击事件的文字封装在ClickSpanModel中,普通文本放在TextSpanModel中。

private List<SpanTextView.BaseSpanModel> createSpanTexts(){
        List<SpanTextView.BaseSpanModel> spanModels = new ArrayList<>();
        SpanTextView.ClickSpanModel spanModel = new SpanTextView.ClickSpanModel();
        spanModel.setContent("Mary");
        spanModels.add(spanModel);

        SpanTextView.TextSpanModel textSpanModel = new SpanTextView.TextSpanModel();
        textSpanModel.setContent(" commented ");
        spanModels.add(textSpanModel);

        spanModel = new SpanTextView.ClickSpanModel();
        spanModel.setContent("Lucy");
        spanModels.add(spanModel);

        textSpanModel = new SpanTextView.TextSpanModel();
        textSpanModel.setContent("'s video,say:Your video is very nice.");
        spanModels.add(textSpanModel);
        return spanModels;
    }

调用方式如下

SpanTextView spannableTextView = (SpanTextView) findViewById(R.id.spanableText);
spannableTextView.setText(createSpanTexts(), new SpanTextView.SpanClickListener() {
      @Override
      public void OnClickListener(int position) {
          ToastUtil.show("You clicked "+createSpanTexts().get(position).getContent()+".");
     }
});

相关文章

网友评论

      本文标题:Android分段可点击TextView

      本文链接:https://www.haomeiwen.com/subject/bivrcctx.html