将 TextView 格式化为看起来像链接
Posted
技术标签:
【中文标题】将 TextView 格式化为看起来像链接【英文标题】:Format TextView to look like link 【发布时间】:2012-08-02 23:11:30 【问题描述】:我一直在使用android:autoLink
来格式化链接等,但我需要使用android:onClick
,所以在这种情况下我不能使用它。原因是我发现误点击电话号码太容易了,所以我准备拦截点击确认Dialog
然后拨打电话。
有没有一种简单的方法可以让我的TextView
中的电话号码看起来像一个普通的可点击链接?我翻遍了 Android 源代码,但找不到任何特定的样式供我参考。
【问题讨论】:
一种解决方案是扩展 ClickableSpan 以执行您自己的单击链接的自定义处理:developer.android.com/reference/android/text/style/… 另请查看此线程:***.com/questions/11413399/… 【参考方案1】:这是最短的解决方案:
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(...) ,其中的文本有链接标签 ("") 。
如果您希望获得其他解决方案,请查看this post。
【讨论】:
【参考方案2】: 您可以创建一个 colors.xml 资源文件,其中包含颜色。请看Colors 如果你想给你的文字加下划线,那么请看看这个帖子: Underline 别忘了将android:clickable="true"
或setClickable(true)
添加到
你的 TextView 让它们可点击!
【讨论】:
【参考方案3】:Linkify 是一个很棒的类,它寻找复杂的模式,如 URL、电话号码等,并将它们转换为 URLSpans。我没有重写现有的正则表达式,而是扩展了 URLSpan 类并创建了一个方法,将only电话 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()
方法。明白我写这个是为了好玩,可能还有其他方法可以做到这一点,但我目前不知道它们。希望这会有所帮助!
【讨论】:
谢谢,这看起来很不错!我将尝试尽快实施它,看看它是如何进行的。 :)【参考方案4】:要为 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);
这应该可行。让我知道你的进展。
【讨论】:
只需用字符串替换内容,然后只有您的代码可以正常工作。因为这里没有内容。【参考方案5】:带有kotlin扩展功能(如果你不需要真实链接的点击效果)
fun TextView.hyperlinkStyle()
setText(
SpannableString(text).apply
setSpan(
URLSpan(""),
0,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
,
TextView.BufferType.SPANNABLE
)
如何使用
yourTextView.hyperlinkStyle()
【讨论】:
【参考方案6】:有一个更好的答案。这就是我所做的。
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 方法点击链接时,你可以去任何你喜欢的地方
【讨论】:
【参考方案7】:简单地划线:
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
【讨论】:
以上是关于将 TextView 格式化为看起来像链接的主要内容,如果未能解决你的问题,请参考以下文章
SQLite 片段函数实现不会在 TextView 中将文本格式化为 HTML
使用 DecimalFormat 进行格式化会引发异常 - “无法将给定对象格式化为数字”