zoukankan      html  css  js  c++  java
  • 解析TextView中的URL等指定特殊字符串与点击事件

          使用TextView时,有时可能需要给予TextView里的特定字符串,比如URL,数字特别的样式,必希望能够添加点击事件。比如发短信时,文字里的url就可以点击直接打开浏览器,数字可以点击拨打电话。

    Android提供了SpannableString类来对TextView的内容进行处理,具体步骤:

     

    1.new一个SpannableString对象,传入需要显示在TextView上的内容;

     

    2.对内容进行处理(比如用正则表达式解析出URL或数字等等,并指定样式),这部分的核心就是调用SpannableString对象的setSpan()方法;

    public void setSpan(Object what, int start, int end, int flags);

    可以看到有四个参数,start 和 end 是意味着你要改变的是该字符串下标start到end的部分,what可以传入对start到end的文本的处理方式或者样式,也可以传入你指定的东西来取代文本,比如图片。flags总共有四种,他意味着是否影响指定处前一个或后一个字符串

     

    3.TextView.setText(spannableString),由于SpannableString实现了CharSequence,所以TextView可以直接set。

    注意到这里TextView的指定内容就已经实现指定样式了。,但是如果想要添加点击事件,还需要让TextView调用setMovementMethod(MovementMethod movement)来实现点击事件。

    下面贴出我的Demo,实现将TextView里的数字标注出来,点击数字将弹出Toast将数字显示出来。

        private void init() {
            tvMain.setMovementMethod(LinkMovementMethod.getInstance());
            SpannableString s = new SpannableString(CONTENT);
            filterNumber(s);
            tvMain.setText(s);
        }
    
        private static final String REG = "\d+";
    
        public class TextClickableSpan extends ClickableSpan {
            private String text;
    
            public TextClickableSpan(String text) {
                this.text = text;
            }
    
            @Override
            public void onClick(View view) {
                Toast.makeText(MyActivity.this,text,Toast.LENGTH_SHORT).show();
            }
        }
    
    private void filterNumber(Spannable s) {
            Matcher m = Pattern.compile(REG).matcher(s.toString());
            while (m.find()) {
                String text = m.group();
                TextClickableSpan span = new TextClickableSpan(text);
                s.setSpan(span,m.start(),m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

    代码很简单,首先要说的是ClickableSpan,因为当你点击该特定字符串时,LinkMovementMethod的onTouchEvent()方法,将会根据你点击的位置获得ClickableSpan对象,并执行该对象的onClick方法。而这个ClickableSpan需要在setSpan时传入(这个地方不仅可以传入ClickableSpan还有诸如ImageSpan等等,不过如果要可以点击的话,要传入ClickableSpan。其他的这里不一一赘述)。

    然后我的filterNumber方法,就是利用正则表达式来过滤数字,并调用setSpan一一传入相应start和end。

    最后,要说下setSpan的最后一个参数flags:

    Spanned.SPAN_INCLUSIVE_EXCLUSIVE 是当前这个设置包括前面,不包括后面

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 当前设置前后不包括

    Spanned.SPAN_INCLUSIVE _INCLUSIVE 当前设置包括前面,包括后面

    Spanned.SPAN_EXCLUSIVE_INCLUSIVE 当前设置不包括前面,包括后面

  • 相关阅读:
    HTML和XHTML知识总结
    理解margin-left:-100%
    git clean的用法
    vue路由传参的三种基本方式
    vertical-align属性
    纯CSS制作各种图形(多图预警)
    css伪元素:before和:after用法详解
    前端注册登录的业务流程
    Vue-cli 中为单独页面设置背景图片铺满全屏的方法
    vscode 开启对 webpack alias(文件别名) 引入的智能提示
  • 原文地址:https://www.cnblogs.com/luction/p/3643009.html
Copyright © 2011-2022 走看看