I want to make a part of my text in my TextView
a clickable Url
, I know I can use SpannableString
to achieve a clickable part by using something like this
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);
But if I use a string from my localization resources as my SpannableString
, then the length of the string could vary, which means the wrong set of characters may be clickable. How would I go about this?
This example demonstrates how do I set the part of the Android textView as clickable. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.
All I've found are two sub-optimal ways. It does still use Spannable, but hear me out, as I'm in the exact situation you speak of.
First, there's the method that you mention, and you can go through a giant switch statement of languages and solve the span for each one. This is horrific, of course, but it is the most accurate way to ensure the right spans are clickable.
E.g.
if (Locale.getDefault().getLanguage().contentEquals("en") {
// spannable gets substring a,b
else if (Locale.getDefault().getLanguage().contentEquals("fr") {
// spannable gets substring x,y
}
Again, not good.
Now, if your translators can handle the string broken up into substrings, 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>
Then you can programmatically build the Spannable strings like:
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);
Like I say, it truly is a "least worse" kind of situation, but I thought I'd at least throw it out there, as I don't think there's any other ways to do this with localization, as the the compiler has no knowledge of how a string is translated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With