由于工作上的需求,类似于淘宝京东在获取物流信息时电话号码高亮显示,并触摸和点击电话号码时跳转到拨打电话.刚开始一时没想到什么好的方法,最后通过查找资料,看到了Span完全能够实现需求,并且使用效果好的不行.话不多说先上效果图如下:
效果图如上,现在分析实现的核心代码如下:
//初始化SpannableStringBuilder
mSpannableStringBuilder = new SpannableStringBuilder(mContent);
//初始化需要高亮显示的文字和对其设置点击事件
SpannableStringBuilder spannableStringBuilder = initClickText(mSpannableStringBuilder, mContent);
//把mSpannableStringBuilder设置给对应的文本控件
mTv.setText(spannableStringBuilder);
//对文本控件设置触摸事件,当触摸区域是电话号码时拨打电话
mTv.setOnTouchListener((v, event) -> {
boolean ret = false;
CharSequence text = ((TextView) v).getText();
Spannable stext = Spannable.Factory.getInstance().newSpannable(text);
TextView widget = (TextView) v;
int action = event.getAction();
//根据点击判断是否在spannable对象上;
if (action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = stext.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
}
ret = true;
}
}
return ret;
});
/**
* 获取文字中的电话号码 并高亮显示和设置点击事件
* @param spannableStringBuilder
* @param text 文字内容
* @return
*/
private SpannableStringBuilder initClickText(SpannableStringBuilder spannableStringBuilder, String text) {
Pattern patternPhone = Pattern.compile("\\d{3}-\\d{8}|\\d{4}-\\d{7}|\\d{11}");
Matcher matcherPhone = patternPhone.matcher(text);
int start = 0;
//遍历取出字符串中所有的符合条件的;
while (matcherPhone.find(start)) {
start = matcherPhone.end();
spannableStringBuilder.setSpan(new ForegroundColorSpan(CommonUtils.getColor(this, R.color.colorPrimary)), matcherPhone.start(), matcherPhone.end(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableStringBuilder.setSpan(new MyUrlSpan(matcherPhone.group()), matcherPhone.start(),
matcherPhone.end(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
if (start >= text.length()) {
break;
}
}
return spannableStringBuilder;
}
/**
* Span点击的实现类
*/
private class MyUrlSpan extends ClickableSpan {
private String mUrl;
public MyUrlSpan(String url) {
mUrl = url;
}
//点击链接下划线,弹出dialog,提示提电话,或者发短信;通用的dialog我上篇文章有介绍.
@Override
public void onClick(View widget) {
CommonBaseDialog.showDialog(SpanActivity.this, R.layout.common_dialog)
.setText(R.id.title, getPhoneText(mUrl))
.setViewVisibility(R.id.content, View.GONE)
.setDialogLocation(Gravity.CENTER, 60, 0, 60, 0)
.setViewListener((dialog, viewId) -> {
switch (viewId) {
case R.id.confirm:
Intent intent = new Intent(Intent.ACTION_DIAL);
Uri data = Uri.parse("tel:" + mUrl);
intent.setData(data);
SpanActivity.this.startActivity(intent);
case R.id.cancel:
dialog.dismiss();
break;
}
}, R.id.cancel, R.id.confirm);
}
}
这样就完美的实现了上述的需求希望这篇文章对你有所帮助谢谢!!!!!!!!!!