我想将TextView
文本的一部分变成可点击的Url
,我知道我可以使用SpannableString
通过使用这样的东西来实现可点击的部分
SpannableString mySpannableString = new SpannableString("a string");
ClickableSpan myClickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
// do something
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
mySpannableString.setSpan(myClickableSpan, 2, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
但是,如果我使用本地化资源中的字符串作为我的SpannableString
,那么字符串的长度可能会有所不同,这意味着可以单击错误的字符集。我该怎么做?
我发现的只是两种次优方法。它仍然使用Spannable,但请听我说,因为我处于您所说的确切情况。
首先,有你提到的方法,你可以通过一个巨大的语言开关语句并解决每个语言的跨度。当然,这很可怕,但这是确保正确跨度可点击的最准确方法。
例如
if (Locale.getDefault().getLanguage().contentEquals("en") {
// spannable gets substring a,b
else if (Locale.getDefault().getLanguage().contentEquals("fr") {
// spannable gets substring x,y
}
再次,不好。
现在,如果您的翻译人员可以处理分解为子字符串的字符串,IE
<string name=suba>Some intro text to</string>
<string name=sublinka>linkable A</string>
<string name=subb>and then some intro text to</string>
<string name=sublinka>linkable B</string>
然后,您可以通过编程方式构建 Spannable 字符串,如下所示:
TextView textView = (TextView) findViewById(R.id.text_view);
String subA = getString(R.string.suba);
String subLinkA = getString(R.string.sublinka);
String subB = getString(R.string.subb);
String subLinkB = getString(R.string.sublinkb);
SpannableStringBuilder spannableText = new
SpannableStringBuilder(subA);
spannableText.append(subLinkA);
spannableText.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(this, "Sub Link A Clicked", Toast.LENGTH_SHORT).show();
}
}, spannableText.length() - subLinkA.length(), spannableText.length(), 0);
spannableText.append(subB);
spannableText.append(subLinkB);
spannableText.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(this, "Sub Link B Clicked", Toast.LENGTH_SHORT).show();
}
}, spannableText.length() - subLinkB.length(), spannableText.length(), 0);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannableText, TextView.BufferType.SPANNABLE);
就像我说的,这确实是一种"最糟糕"的情况,但我想我至少会把它扔在那里,因为我认为没有任何其他方法可以通过本地化做到这一点,因为编译器不知道字符串是如何翻译的。
字符串中.xml像这样做html:
中文 : <![CDATA[Makan <b>daging</b> adalah terlalu banyak karbohidrat]]>
印度尼西亚 : <![CDATA[Eating <b>meat</b> is too much carbohydrates]]>
然后在您的活动中,您可以跟踪跨度位置并添加ClickableSpan
:
class MainActivity: AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupView()
}
private fun setupView() {
val htmlSpan = SpannableString(HtmlCompat.fromHtml(
getString(R.string.click_me_button),
HtmlCompat.FROM_HTML_MODE_COMPACT
))
val styleSpan = htmlSpan.getSpans(0, htmlSpan.length, StyleSpan::class.java).first()
val spanStart = htmlSpan.getSpanStart(styleSpan)
val spanEnd = htmlSpan.getSpanEnd(styleSpan)
val clickSpan = object:ClickableSpan() {
override fun onClick(widget: View) {
Toast.makeText(this@MenghubungkanProdukActivity, "Hehehehe", Toast.LENGTH_LONG).show()
Timber.d("HEHEHE")
}
}
htmlSpan.setSpan(clickSpan, spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.textWarning.text = htmlSpan
binding.textWarning.movementMethod = LinkMovementMethod.getInstance()
}
}
来源 : 本地化可点击跨度安卓