Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android studio make a part of a string (in a Textview) from localization resources a clickable url?

Tags:

android

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?

like image 359
Simon Andersson Avatar asked Jan 18 '17 15:01

Simon Andersson


People also ask

How do you set the part of the text view is clickable in android?

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.


1 Answers

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.

like image 179
Wes Winn Avatar answered Sep 28 '22 16:09

Wes Winn