Span使用之文字高亮及點選事件
阿新 • • 發佈:2019-02-16
由於工作上的需求,類似於淘寶京東在獲取物流資訊時電話號碼高亮顯示,並觸控和點選電話號碼時跳轉到撥打電話.剛開始一時沒想到什麼好的方法,最後通過查詢資料,看到了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);
}
}
這樣就完美的實現了上述的需求希望這篇文章對你有所幫助謝謝!!!!!!!!!!