富文本点击类似于QQ点赞好友

Spannable做富文本部分点击时跳转,类似于QQ的点赞好友的点击跳转效果.QQ空间的图片


实现代码:




public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView t1 = (TextView) findViewById(R.id.tv1);


        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 20; i++) {
            sb.append("基友" + i + "、");
        }


        String friends = sb.substring(0, sb.lastIndexOf("、")).toString();


        t1.setMovementMethod(LinkMovementMethod.getInstance());
        t1.setText(addClickPart(friends), TextView.BufferType.SPANNABLE);
    }


//    定义一个点击每个部分文字的处理方法
    private SpannableStringBuilder addClickPart(String str) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(str);
        String[] friends = str.split("、");
        if (friends.length > 0) {
            for (int i = 0; i < friends.length; i++) {
                final String name = friends[i];
                final int start = str.indexOf(name) ;
                if(start != -1) {
                    ssb.setSpan(new ClickableSpan() {
                        @Override
                        public void onClick(View widget) {
                            Toast.makeText(MainActivity.this, name,
                                    Toast.LENGTH_SHORT).show();
                        }


                        @Override
                        public void updateDrawState(TextPaint ds) {
                            super.updateDrawState(ds);
                            //删除下划线,设置字体颜色为红色
                            ds.setColor(Color.RED);
                            ds.setUnderlineText(false);
                        }
                    }, start, start + name.length(), 0);
                }
            }
        }
        return ssb.append("等" + friends.length + "个人觉得很赞");
    }
}

布局文件比较简单这里就不粘了,就是一个TextView.

效果如下:


其中LinkMovementMethod.的解释如下:
比如它的onKeyDown调用ClickableSpan的onClick
URLSpan实现了ClickableSpan 
用户点击一个url的话,就会调用LinkMovementMethod::onKeyDown,继而调用URLSpan的onClick,
我们看看URLSpan::onClick的实现
    @override
    public void onClick(View widget) {
        Uri uri = Uri.parse(getURL());
        Context context = widget.getContext();
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
        context.startActivity(intent);
    }
它实际上是启动了一个activity,可能是web/email或者其他的满足intent filter/url schema的activity.

以下是本猿的教训:

啥话不说直接上代码想不到displayName的用处,只想着用来和输入的msgText来作对比想匹配,还搞了个正则表达式,遍历了两次功能虽然是实现了但是却是很麻烦,
自己想不到其实 final String name = stockList[i];是可以用listStock来替换的.脑子真的转的很慢.
//        Pattern p = Pattern.compile("( \\$)(.*?)(\\$ )");
//        Matcher matcher = p.matcher(ssb);
//        List list = new ArrayList();
//        int j = 0;
//        while (matcher.find()) {
//            searchStocks = listStock.get(j);
//            String sel = matcher.group();
//            if (searchStocks.getDisplayname().equals(sel)) {
//                list.add(matcher.group());
//                j++;
//            }
//        }


//        String[] stockList = (String[]) list.toArray(new String[0]);
//        MyLog.e("pipei  " + Arrays.toString(stockList));
//
//        if (stockList.length > 0) {
//            for (int i = 0; i < stockList.length; i++) {
//
//                final String name = stockList[i];
//                final int start = str.indexOf(name);
//                ssb.setSpan(new ClickableSpan() {
//                    @Override
//                    public void onClick(View widget) {
//                        Toast.makeText(context, name,
//                                Toast.LENGTH_SHORT).show();
//                    }
//
//                    @Override
//                    public void updateDrawState(TextPaint ds) {
//                        super.updateDrawState(ds);
//                        ds.setUnderlineText(true);
//                    }
//                }, start, start + name.length(), 0);
//            }

//        }


看我工程师老大直接就用了如下代码,一次遍历就搞定了,前提是displayName唯一.
  SpannableStringBuilder ssb = new SpannableStringBuilder(str);


        for (int i = 0; i < listStock.size(); i++) {
            StockElem.SearchStocks searchStocks = listStock.get(i);
            final String disPlayName = searchStocks.getDisplayname();
            final int start = str.indexOf(disPlayName);
            if (start != -1) {
                ssb.setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        Toast.makeText(context, disPlayName,
                                Toast.LENGTH_SHORT).show();


                    }


                    @Override
                    public void updateDrawState(TextPaint ds) {
                        super.updateDrawState(ds);
                        ds.setUnderlineText(true);
                    }
                }, start, start + disPlayName.length(), 0);
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值