我有文本“Android是一个软件堆栈”。在这个文本中,我想设置“堆栈”文本为可点击。所以,如果你点击它,它将重定向到一个新的活动(不在浏览器中)。
我试过了,但没有找到解决办法。
我有文本“Android是一个软件堆栈”。在这个文本中,我想设置“堆栈”文本为可点击。所以,如果你点击它,它将重定向到一个新的活动(不在浏览器中)。
我试过了,但没有找到解决办法。
当前回答
我的功能使TextView内的多个链接 更新2020:现在这个函数能够支持多个相同的文本链接在1 TextView,但记得把链接在正确的顺序
fun TextView.makeLinks(vararg links: Pair<String, View.OnClickListener>) {
val spannableString = SpannableString(this.text)
var startIndexOfLink = -1
for (link in links) {
val clickableSpan = object : ClickableSpan() {
override fun updateDrawState(textPaint: TextPaint) {
// use this to change the link color
textPaint.color = textPaint.linkColor
// toggle below value to enable/disable
// the underline shown below the clickable text
textPaint.isUnderlineText = true
}
override fun onClick(view: View) {
Selection.setSelection((view as TextView).text as Spannable, 0)
view.invalidate()
link.second.onClick(view)
}
}
startIndexOfLink = this.text.toString().indexOf(link.first, startIndexOfLink + 1)
// if(startIndexOfLink == -1) continue // todo if you want to verify your texts contains links text
spannableString.setSpan(
clickableSpan, startIndexOfLink, startIndexOfLink + link.first.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
this.movementMethod =
LinkMovementMethod.getInstance() // without LinkMovementMethod, link can not click
this.setText(spannableString, TextView.BufferType.SPANNABLE)
}
使用
my_text_view.makeLinks(
Pair("Terms of Service", View.OnClickListener {
Toast.makeText(applicationContext, "Terms of Service Clicked", Toast.LENGTH_SHORT).show()
}),
Pair("Privacy Policy", View.OnClickListener {
Toast.makeText(applicationContext, "Privacy Policy Clicked", Toast.LENGTH_SHORT).show()
}))
XML
<TextView
android:id="@+id/my_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please accept Terms of Service and Privacy Policy"
android:textColorHighlight="#f00" // background color when pressed
android:textColorLink="#0f0"
android:textSize="20sp" />
DEMO
参考
解决方案清除链接高亮选择遵循https://stackoverflow.com/a/19445108/5381331
其他回答
您可以使用此方法设置可点击的值
public void setClickableString(String clickableValue, String wholeValue, TextView yourTextView){
String value = wholeValue;
SpannableString spannableString = new SpannableString(value);
int startIndex = value.indexOf(clickableValue);
int endIndex = startIndex + clickableValue.length();
spannableString.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false); // <-- this will remove automatic underline in set span
}
@Override
public void onClick(View widget) {
// do what you want with clickable value
}
}, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourTextView.setText(spannableString);
yourTextView.setMovementMethod(LinkMovementMethod.getInstance()); // <-- important, onClick in ClickableSpan won't work without this
}
下面是如何使用它:
TextView myTextView = findViewById(R.id.myTextView);
setClickableString("stack", "Android is a Software stack", myTextView);
Kotlin上复杂但通用的解决方案
/*
* Receive Pair of Text and Action and set it clickable and appearing as link
* */
fun TextView.setClickableText(vararg textToSpanAndClickAction: Pair<String, (String) -> Unit>) {
val builder = SpannableStringBuilder(text.toString())
textToSpanAndClickAction.forEach { argPair ->
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
argPair.second.invoke(argPair.first)
}
}
this.text.toString().let { fullText ->
val indexOfFirst = fullText.indexOf(argPair.first)
val indexOfLast = indexOfFirst + argPair.first.length
if (indexOfFirst < 0){
//No match found
return
}else{
builder.setSpan(
clickableSpan,
indexOfFirst,
indexOfLast,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
}
this.text = builder
this.movementMethod = LinkMovementMethod.getInstance()
}
Kotlin Spannable
这是java爱好者的Boom Check:D 我们可以根据自己的需要进行修改:
List<Pair<String, View.OnClickListener>> pairsList = new ArrayList<>();
pairsList.add(new Pair<>("38,50", v -> {
Intent intent = new Intent(SignUpActivity.this, WebActivity.class);
intent.putExtra("which", "tos");
startActivity(intent);
}));
pairsList.add(new Pair<>("81,95", v -> {
Intent intent = new Intent(SignUpActivity.this, WebActivity.class);
intent.putExtra("which", "policy");
startActivity(intent);
}));
makeLinks(pairsList); // Method calling
private void makeLinks(List<Pair<String, View.OnClickListener>> pairsList) {
SpannableString ss = new SpannableString(By signing up, I’m agree to PAKRISM’s Terms of Use and confirms that I have read Privacy Policy);
for (Pair<String, View.OnClickListener> pair : pairsList) {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//Toast.makeText(MyApplication.getAppContext(), "Clicked!", Toast.LENGTH_SHORT).show();
pair.second.onClick(textView);
}
@Override
public void updateDrawState(TextPaint ds) {
ds.linkColor = ContextCompat.getColor(SignUpActivity.this, R.color.primary_main);
ds.setUnderlineText(true);
super.updateDrawState(ds);
}
};
String[] indexes = pair.first.split(",");
ss.setSpan(clickableSpan, Integer.parseInt(indexes[0]), Integer.parseInt(indexes[1]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
TextView tv = findViewById(R.id.txtView);
tv.setText(ss);
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
它对文本的某些部分的可点击部分非常有帮助。
点是正则表达式中的一个特殊字符。如果你想要分隔圆点,需要将圆点转义为\\。而不是仅仅将"."传递给可扩展的文本方法。或者,也可以使用正则表达式[。在Java中通过一个点来分隔字符串。
你可以像本文中描述的那样使用ClickableSpan
示例代码:
TextView myTextView = new TextView(this);
String myString = "Some text [clickable]";
int i1 = myString.indexOf("[");
int i2 = myString.indexOf("]");
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
myTextView.setText(myString, BufferType.SPANNABLE);
Spannable mySpannable = (Spannable)myTextView.getText();
ClickableSpan myClickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) { /* do something */ }
};
mySpannable.setSpan(myClickableSpan, i1, i2 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
参考