1. 程式人生 > >Span使用之文字高亮及點選事件

Span使用之文字高亮及點選事件

由於工作上的需求,類似於淘寶京東在獲取物流資訊時電話號碼高亮顯示,並觸控和點選電話號碼時跳轉到撥打電話.剛開始一時沒想到什麼好的方法,最後通過查詢資料,看到了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);


        }
    }

這樣就完美的實現了上述的需求希望這篇文章對你有所幫助謝謝!!!!!!!!!!