我有文本“Android是一个软件堆栈”。在这个文本中,我想设置“堆栈”文本为可点击。所以,如果你点击它,它将重定向到一个新的活动(不在浏览器中)。
我试过了,但没有找到解决办法。
我有文本“Android是一个软件堆栈”。在这个文本中,我想设置“堆栈”文本为可点击。所以,如果你点击它,它将重定向到一个新的活动(不在浏览器中)。
我试过了,但没有找到解决办法。
当前回答
使用URLSpan类获取url
val spans: Array<URLSpan> = result.getSpans(0, result.length, URLSpan::class.java)
方法
fun TextView.createClickable(string: String, action:(String)->Unit ) {
text = HtmlCompat.fromHtml(string, HtmlCompat.FROM_HTML_MODE_LEGACY)
val result = SpannableString(text)
val spans = result.getSpans(0, result.length, URLSpan::class.java)
for (span in spans) {
val link:Pair<String, View.OnClickListener> = Pair(span.url, View.OnClickListener {
action(span.url)
})
val start = result.getSpanStart(span)
val end = result.getSpanEnd(span)
val flags = result.getSpanFlags(span)
result.removeSpan(span)
val clickableSpan: ClickableSpan = object : ClickableSpan() {
override fun onClick(textView: View) {
textView.invalidate()
link.second.onClick(textView)
}
override fun updateDrawState(textPaint: TextPaint) {
super.updateDrawState(textPaint)
textPaint.isUnderlineText = false
}
}
result.setSpan(clickableSpan, start, end, flags)
this.movementMethod = LinkMovementMethod.getInstance()
this.setText(result, TextView.BufferType.SPANNABLE)
}
}
Use
示例文本:Android是一个软件堆栈,它非常棒
包装你的可点击的文本内锚标签
比如:Android是一个软件<a href='https://example.com/stack'> Stack </a>和它' <a href='https://example.com/awesome'> Awesome </a>。
val str = "Android is a Software <a href='https://example.com/stack'> Stack </a> and it' <a href='https://example.com/awesome'> Awesome </a>."
textView.createClickable(str) {
when(it) {
"https://example.com/stack"->{
startActivity(Intent(this,StackActivity::class.java))
}
"https://example.com/awesom"->{
startActivity(Intent(this,AwesomeActivity::class.java))
}
}
}
其他回答
您可以使用示例代码。您希望了解关于ClickableSpan的详细信息。请检查这份文件
SpannableString myString = new SpannableString("This is example");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
ToastUtil.show(getContext(),"Clicked Smile ");
}
};
//For Click
myString.setSpan(clickableSpan,startIndex,lastIndex,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//For UnderLine
myString.setSpan(new UnderlineSpan(),startIndex,lastIndex,0);
//For Bold
myString.setSpan(new StyleSpan(Typeface.BOLD),startIndex,lastIndex,0);
//Finally you can set to textView.
TextView textView = (TextView) findViewById(R.id.txtSpan);
textView.setText(myString);
textView.setMovementMethod(LinkMovementMethod.getInstance());
提供的解决方案相当不错。然而,我通常使用更简单的解决方案。
这是一个linkify效用函数
/**
* Method is used to Linkify words in a TextView
*
* @param textView TextView who's text you want to change
* @param textToLink The text to turn into a link
* @param url The url you want to send the user to
*/
fun linkify(textView: TextView, textToLink: String, url: String) {
val pattern = Pattern.compile(textToLink)
Linkify.addLinks(textView, pattern, url, { _, _, _ -> true })
{ _, _ -> "" }
}
使用这个函数非常简单。这里有一个例子
// terms and privacy
val tvTerms = findViewById<TextView>(R.id.tv_terms)
val tvPrivacy = findViewById<TextView>(R.id.tv_privacy)
Utils.linkify(tvTerms, resources.getString(R.string.terms),
Constants.TERMS_URL)
Utils.linkify(tvPrivacy, resources.getString(R.string.privacy),
Constants.PRIVACY_URL)
我做了这个helper方法,以防有人需要从字符串中开始和结束位置。
public static TextView createLink(TextView targetTextView, String completeString,
String partToClick, ClickableSpan clickableAction) {
SpannableString spannableString = new SpannableString(completeString);
// make sure the String is exist, if it doesn't exist
// it will throw IndexOutOfBoundException
int startPosition = completeString.indexOf(partToClick);
int endPosition = completeString.lastIndexOf(partToClick) + partToClick.length();
spannableString.setSpan(clickableAction, startPosition, endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
targetTextView.setText(spannableString);
targetTextView.setMovementMethod(LinkMovementMethod.getInstance());
return targetTextView;
}
下面是你如何使用它
private void initSignUp() {
String completeString = "New to Reddit? Sign up here.";
String partToClick = "Sign up";
ClickableTextUtil
.createLink(signUpEditText, completeString, partToClick,
new ClickableSpan() {
@Override
public void onClick(View widget) {
// your action
Toast.makeText(activity, "Start Sign up activity",
Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// this is where you set link color, underline, typeface etc.
int linkColor = ContextCompat.getColor(activity, R.color.blumine);
ds.setColor(linkColor);
ds.setUnderlineText(false);
}
});
}
这是一个Kotlin方法,使TextView的部分可点击:
private fun makeTextLink(textView: TextView, str: String, underlined: Boolean, color: Int?, action: (() -> Unit)? = null) {
val spannableString = SpannableString(textView.text)
val textColor = color ?: textView.currentTextColor
val clickableSpan = object : ClickableSpan() {
override fun onClick(textView: View) {
action?.invoke()
}
override fun updateDrawState(drawState: TextPaint) {
super.updateDrawState(drawState)
drawState.isUnderlineText = underlined
drawState.color = textColor
}
}
val index = spannableString.indexOf(str)
spannableString.setSpan(clickableSpan, index, index + str.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = spannableString
textView.movementMethod = LinkMovementMethod.getInstance()
textView.highlightColor = Color.TRANSPARENT
}
它可以被多次调用,在TextView中创建几个链接:
makeTextLink(myTextView, str, false, Color.RED, action = { Log.d("onClick", "link") })
makeTextLink(myTextView, str1, true, null, action = { Log.d("onClick", "link1") })
创建优雅的Kotlin方式与扩展:
fun TextView.setClickableText(text: Spanned,
clickableText: String,
@ColorInt clickableColor: Int,
clickListener: () -> Unit) {
val spannableString = SpannableString(text)
val startingPosition: Int = text.indexOf(clickableText)
if (startingPosition > -1) {
val clickableSpan: ClickableSpan = object : ClickableSpan() {
override fun onClick(textView: View) {
clickListener()
}
override fun updateDrawState(textPaint: TextPaint) {
super.updateDrawState(textPaint)
textPaint.isUnderlineText = false
}
}
val endingPosition: Int = startingPosition + clickableText.length
spannableString.setSpan(clickableSpan, startingPosition,
endingPosition, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
spannableString.setSpan(ForegroundColorSpan(clickableColor), startingPosition,
endingPosition, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
movementMethod = LinkMovementMethod.getInstance()
highlightColor = Color.TRANSPARENT
}
setText(spannableString)
}