Android 实现TextView的部分文字和网络链接及电话号码点击监听

0
回复
158
查看
[复制链接]

2

主题

2

帖子

15

安币

初级码农

Rank: 1

发表于 2019-4-16 19:10:01 | 显示全部楼层 |阅读模式
如果对本篇文章感兴趣,请前往,原文地址:http://www.apkbus.com/blog-980256-79890.html

## 前言最近在写项目的时候遇到了一个这样的需求,要像qq一样,点击评论的者的名字要跳转评论者的用户信息界面,并且点击评论信息中的web链接要跳转到WebActivity,同时如果是其他数字的话要像qq一样点击并显示底部Dialog提示是播打电话还是复制号码。## 效果先给大家看看效果![](//upload-images.jianshu.io/upload_images/7078775-e4cdc0b27b0cf004.png)下面的评论由一个TextView显示,其实显示为淡蓝的都是可以点击的区域。## 思路因为没做过肯定是先百度了解一下,大部分的处理都是先设置TextView的autolink,然后系统会给你判断TextView中是否可以匹配到链接。然后通过SpannableStringBuilder来设置点击事件,当百度的部分有限,只能了解到web链接的点击事件监听,所以我在此基础上并综合直接给TextView设置部分点击的知识做了一些尝试,但是出现了一些问题,就是当autolink设置的过滤在TextView中的文字中没有匹配到的时候不能获取到Spannable对象。我就自己new了一个,但是却不能处罚点击事件,最后找到了一个TextViewtv.setMovementMethod(LinkMovementMethod.getInstance());方法,设置之后才能触发点击事件。## 实现步骤首先给你的TextView设置autoLink属性如下```android:autoLink="all"```然后实现一个初始化web和数字链接点击的监听,如下```public static SpannableStringBuilder getWebLinkStyle(CharSequence text, Context context) {    if (text instanceof Spannable) {      int end = text.length();      Spannable sp = (Spannable) text;      URLSpan urls[] = sp.getSpans(0, end, URLSpan.class);      SpannableStringBuilder style = new SpannableStringBuilder(text);      style.clearSpans();      for (URLSpan urlSpan : urls) {        ClickableSpan myURLSpan = new ClickableSpan() {          @Override          public void onClick(@NonNull View view) {            if (urlSpan.getURL().startsWith("http")) {              WebActivity.startWebBrowsing(context, urlSpan.getURL(), "");            } else {              String number = urlSpan.getURL();              if (number.contains(":")) {                number = number.split[1](":");              }              showBottomSheetDialog(context, number);            }          }        };        style.setSpan(myURLSpan, sp.getSpanStart(urlSpan),            sp.getSpanEnd(urlSpan),            Spannable.SPAN_EXCLUSIVE_INCLUSIVE);      }      return style;    }    return null;  } public static void showBottomSheetDialog(Context context, final String number) {    BottomSheetDialog dialog = new BottomSheetDialog(context);    View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_bottom, null);    TextView tvTitle = dialogView.findViewById(R.id.tv_title);    tvTitle.setText(String.format("%s\n可能是一个电话号码或者其他联系方式,你可以", number));    TextView tvCall = dialogView.findViewById(R.id.tv_call);    tvCall.setOnClickListener(view -> {      Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"   number));      context.startActivity(dialIntent);      dialog.dismiss();    });    TextView tvCopty = dialogView.findViewById(R.id.tv_copy);    tvCopty.setOnClickListener(view -> {      ClipboardManager copy =          (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);      copy.setText(number);      dialog.dismiss();      ToastHelper.toast("已复制到剪切板");    });    TextView tvCancel = dialogView.findViewById(R.id.tv_cancel);    tvCancel.setOnClickListener(view -> dialog.dismiss());    dialog.setContentView(dialogView);    dialog.show();  }```从这个代码里面可以看到text instanceof Spannable成立的时候即TextView中包含符合autolink过滤的链接。我们可以通过URLSpan来找到对应的链接。然后判断是否为web链接和数字,如果是数字的话显示弹窗,提示打电话或者复制。代码如下,同理如果不成立则说明TextView不包含autolink过滤的链接。只能返回null,需要新建一个。接下来就是评论用户设置点击事件了。TextPositionBean是记录每一个评论者用户名在TextView文字中开始和结束的位置,因为在给每个评论者名字加上点击事件时需要给定点击文字的范围。style.setSpan(clickableSpan,textPositionBean.getStart(),textPositionBean.getEnd(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);这其中getStart()和getEnd()就确定了点击文字的范围。代码如下```    SpannableStringBuilder style = UiHelper.getWebLinkStyle(tvCommentInfo.getText(),context);    if (style == null){      style = new SpannableStringBuilder(stringBuilder.toString());    }    for (TextPositionBean textPositionBean : textPositionBeans) {      ClickableSpan clickableSpan = new ClickableSpan() {        @Override        public void onClick(@NonNull View view) {          UserInfoActivity.goToUserInfoActivity(context,textPositionBean.getData());        }      };      style.setSpan(clickableSpan,textPositionBean.getStart(),textPositionBean.getEnd(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);      tvCommentInfo.setMovementMethod(LinkMovementMethod.getInstance());    }    tvCommentInfo.setText(style);```当不存在过滤条件的时候,我就自己手动获取一个,然后根据之前纪录的评论用户的用户名出现的位置,来添加点击事件,并且激活点击响应。即可如果需要BottomSheetDialog的布局文件可看如下代码```              ```  继续阅读全文



想在安卓巴士找到更多优质博文,可移步博客区

如果对本篇文章感兴趣,请前往,
原文地址:
http://www.apkbus.com/blog-980256-79890.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )