Aide学

TextView高级用法

2017-03-05  本文已影响0人  Recker

介绍

最近在做社区类APP,因此避免不了会有如QQ、微信一般的评论,点击TextView发布人或评论人的昵称查看详情,支持超链接,支持emoji表情,下面为大家分享下我在项目中所解决的问题,还希望大家有更好方法可以提出。我均会使用本项目中的图片为大家介绍。

1、文本支持高亮和点击

如下图,我们想在TextView实现高亮,并且还支持点击。


F06DBC62-08FF-4831-BA06-B9C30295A343.png

利用ClickableSpan让TextView支持高亮点击,我们新建几个类继承ClickableSpan,一般我们有两个方法需要重写,分别是updateDrawState和onClick,默认情况下此时TextView会显示默认的主题颜色和有下划线,因此我们可以在updateDrawState对这个进行设置,如下:

@Override
 public void updateDrawState(TextPaint ds) {
      super.updateDrawState(ds);
      //设置高亮颜色
      ds.setColor(ContextCompat.getColor(mContext, R.color.accent));
      //不显示下划线
      ds.setUnderlineText(false);
}

之后,我们可以在onClick方法中对点击事件进行设置,一般我们会尽心跳转操作,因此会传递参数,此时我们可以重写构造方法,对需要的参数进行传递,整个类的完整代码如下:

public class NameClick extends ClickableSpan {
        private String mId;//用户ID

        public NameClick(String id) {
            mId = id;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            //设置高亮颜色
            ds.setColor(ContextCompat.getColor(mContext, R.color.accent));
            //不显示下划线
            ds.setUnderlineText(false);
        }

        @Override
        public void onClick(View view) {
            Intent intent = new Intent(mContext, GroupPersonInfoActivity.class);
            intent.putExtra("id", mId);
            mContext.startActivity(intent);
        }
}

接着我们开始设置TextView,我们结合SpannableString来设置,代码如下:

//设置回复人点击事件,data.getUname为高亮的回复人
SpannableString spanUname = new SpannableString(data.getUname());
spanUname.setSpan(new NameClick(data.getUid()), 0, spanUname.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.textView.append(spanUname);

通过以上设置我们基本可以实现高亮显示,但是此时并不能进行点击,还得为TextView加上一行代码。

//然后TextView支持点击
holder.textView.setMovementMethod(LinkMovementMethod.getInstance());

此时已经可以点击,但是点击后会出现个默认点击背景,可能有时候我们并不需要,或者想改变背景,我们可以通过下面代码实现。

//设置点击效果为透明,您也可以设置其他颜色,这个为点击背景。
holder.textView.setHighlightColor(Color.TRANSPARENT);

TextView完整实现代码如下:

//设置回复人点击事件,data.getUname为高亮的回复人
SpannableString spanUname = new SpannableString(data.getUname());
spanUname.setSpan(new NameClick(data.getUid()), 0, spanUname.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.textView.append(spanUname)
//然后TextView支持点击
holder.textView.setMovementMethod(LinkMovementMethod.getInstance());
//设置点击效果为透明,您也可以设置其他颜色,这个为点击背景。
holder.textView.setHighlightColor(Color.TRANSPARENT);

到此已经可以满足我们的需求了,但是作为RecyclerView或者ListView的item使用时,我们还未遇到点击高亮文本时,item的点击事件也会随之进行响应,并且会有两个点击效果(高亮文本的点背景和item点击背景)这样是非常丑的,因此我想到的是一个是当点击高亮文本时,拦截点击事件让它不传递给item,一个是分治法,为高亮文本和正常文本分别设置ClickableSpan。两个方法均可行,但是在只有本文所描述的情况下使用第一种方法,点击item时,包括高亮文本的整个item都会有点击背景,当然这个是我们不希望看到的,很自然我们得为两者分别设置ClickableSpan。正常文本的代码可如下:

public class ItemClick extends ClickableSpan {

        private int mPosition;//item的所在位置

        public ItemClick(int position) {
            mPosition = position;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            //设为正常文本颜色
            ds.setColor(ContextCompat.getColor(mContext, R.color.primary_text));
            //不显示下划线
            ds.setUnderlineText(false);
        }

        @Override
        public void onClick(View view) {
            //如果设置了点击事件,把事件传递给item
            if (mItemClickListener != null){
                mItemClickListener.onItemClick(view, mPosition);
            }
        }
 }

经过以上实现我们基本可以实现类似QQ、微信的评论回复效果。如果大家遇到有更好的方法或者有错误的问题可以及时评论。

2、让TextView支持emoji表情

如下图,我们可以看到有emoji表情,虽然这个很简单,但是在社交功能中是必不可少的。

F06DBC62-08FF-4831-BA06-B9C30295A343.png
这个我们可以直接下载Apache Commons Lang,然后把jar拿来用,在这里我们可以使用如下代码:
//把字符串转为unicode编码
StringEscapeUtils.escapeJava(etContent.getText().toString())
//解码unicode编码
StringEscapeUtils.unescapeJava(data.getContent())

通过转码和解码我们就可以支持emoji表情,当然这个jar包还是有很多方法的,大家可以自行查询文档学习。

3、让TextView对超链接自动识别,并解决在RecyclerView和ListView遇到的问题。

-----稍后更新。

上一篇下一篇

猜你喜欢

热点阅读