将TextView设置为类似链接的格式



我一直在使用android:autoLink来格式化链接等,但我需要使用android:onClick,所以在这种情况下我不能使用它。原因是我发现不小心点击电话号码太容易了,所以我要用确认Dialog拦截点击,然后打电话。

有没有一种简单的方法可以让我的TextView中的电话号码看起来像一个普通的可点击链接?我浏览了一下安卓的源代码,但找不到任何特定的风格供我参考。

这是最短的解决方案:

final CharSequence text = tv.getText();
final SpannableString spannableString = new SpannableString( text );
spannableString.setSpan(new URLSpan(""), 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(spannableString, TextView.BufferType.SPANNABLE);

遗憾的是,点击的效果并没有显示为在真实的url链接上点击,但你可以这样克服它:

    final CharSequence text = tv.getText();
    final SpannableString notClickedString = new SpannableString(text);
    notClickedString.setSpan(new URLSpan(""), 0, notClickedString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
    final SpannableString clickedString = new SpannableString(notClickedString);
    clickedString.setSpan(new BackgroundColorSpan(Color.GRAY), 0, notClickedString.length(),
            Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    tv.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(final View v, final MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                tv.setText(clickedString);
                break;
            case MotionEvent.ACTION_UP:
                tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
                v.performClick();
                break;
            case MotionEvent.ACTION_CANCEL:
                tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
                break;
            }
            return true;
        }
    });

另一种解决方案是使用Html.fromHtml(…),其中的文本具有链接标记(")。

如果您想要其他解决方案,请查看这篇文章

  • 您可以创建一个colors.xml资源文件,其中包含颜色。请看一下颜色
  • 如果你想在文本下面加下划线,请看一下这篇文章:下划线
  • 不要忘记将android:clickable="true"setClickable(true)添加到您的文本视图,使其可点击

Linkify是一个很棒的类,它搜索URL、电话号码等复杂模式,并将它们转换为URLspan。我没有重写现有的正则表达式,而是扩展了URLSpan类,并创建了一个方法,通过确认对话框将仅的电话URLSpan升级为自定义URLSpan。

我的第一个扩展URLSpan类,ConfirmSpan:

class ConfirmSpan extends URLSpan {
    AlertDialog dialog;
    View mView;
    public ConfirmSpan(URLSpan span) {
        super(span.getURL());
    }
    @Override
    public void onClick(View widget) {
        mView = widget;
        if(dialog == null) {
            AlertDialog.Builder mBuilder = new AlertDialog.Builder(widget.getContext());
            mBuilder.setMessage("Do you want to call: " + getURL().substring(4) + "?");
            mBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            })
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    openURL();
                }
            });
            dialog = mBuilder.create();
        }
        dialog.show();
    }
    public void openURL() {
        super.onClick(mView);
    }
}

下一步交换不同跨度类的方法:

private void swapSpans(TextView textView) {
    Spannable spannable = (Spannable) textView.getText();
    URLSpan[] spans = textView.getUrls();
    for(URLSpan span : spans) {
        if(span.getURL().toString().startsWith("tel:")) {
            spannable.setSpan(new ConfirmSpan(span), spannable.getSpanStart(span), spannable.getSpanEnd(span), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            spannable.removeSpan(span);
        }
    }
}

最后您所需要做的就是创建一个具有autoLink属性的TextView:

android:autoLink="phone"

记住调用swapSpans()方法。要知道我写这篇文章是为了好玩,可能还有其他方法可以做到这一点,但我目前还不知道。希望这能有所帮助!

要给TextView的文本加下划线,您必须执行以下操作:

final TextView text = (TextView) findViewById(R.id.text);
SpannableString string = new SpannableString("This is the uderlined text.");
string.setSpan(new UnderlineSpan(), 0, string.length(), 0);
text.setText(string);

这应该行得通。让我知道你的进展。

带有kotlin扩展功能(如果你不需要像在真实链接上那样的点击效果)

fun TextView.hyperlinkStyle() {
    setText(
        SpannableString(text).apply {
            setSpan(
                URLSpan(""),
                0,
                length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        },
        TextView.BufferType.SPANNABLE
    )
}

如何使用

yourTextView.hyperlinkStyle()

有一个更好的答案。这就是我所做的。

     final SpannableString ss = new SpannableString("Click here to verify Benificiary");
        ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
            }
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setUnderlineText(false);
            }
        };
        ss.setSpan(clickableSpan,0,ss.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setHighlightColor(Color.BLUE);

当用户通过ClickableSpan 的onclick方法点击链接时,你可以去任何你喜欢的地方

只需在下面加下划线:

val myText = "Text to be underlined"
textView.text = Html.fromHtml("<u>$myText</u>")

或与kotlin扩展:

fun TextView.underline() {
    text = Html.fromHtml("<u>${text}</u>")
}

用法:

textView.text = myText
textView.underline()

在android中设置文本样式的更多方法如下:https://medium.com/androiddevelopers/spantastic-text-styling-with-spans-17b0c16b4568

最新更新