pass value to string.xml value that have a link inside it

789 Views Asked by At

I have this value in string.xml file:

<string name="rights">Copyright © All Rights Reserved %1$d <b> <a href="http://www.example.com/">company name</a></b></string>

And I have applied this code that pass to the above text & set that text to the TextView

private void setupAppInfoRights() {

    int currentYear = Calendar.getInstance().get(Calendar.YEAR);
    String rights = String.format(new Locale("en"), getString(R.string.rights), currentYear);
    appInfoRights.setText(rights);
    appInfoRights.setMovementMethod(LinkMovementMethod.getInstance());

}

When I remove the passed value everything goes fine & when the user click on the company name it takes him/her to the company website.

Please note that I have tried autoLink in xml when there is no value passed but it does not work as expected.

But, when I add the passed value & used the code above the company name has no underline & when the user clicks it , it will do nothing.

How to edit my above code to pass the current year & keep the link behavior normal?

Note: I have used String.format to display the current year as English number always despite the other locale numbers.

2

There are 2 best solutions below

0
On BEST ANSWER

I think SpannableStringBuilder is what you are looking for.

  TextView linkTv = (TextView) findViewById(R.id.link_tv);
  linkTv.setMovementMethod(LinkMovementMethod.getInstance());
  Spannable span = (Spannable) linkTv.getText();
  ClickableSpan clickableSpan = new ClickableSpan() {
     @Override
     public void onClick(View widget){
        //open the link
     }
  };
span.setSpan(clickableSpan, 0, span.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 //for bold
span.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), 0, span.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

If you want to make only certain part clickable then toggle the values of 0 and span.length() in setSpan().

0
On

When you have a string resource with both format arguments (like %1$d) and html markup, you have to use a multi-step process to create the styled CharSequence. This extra work is necessary because both Resources.getString(int, Object...) and String.format(String, Object...) can only return String instances, and not other CharSequence subclasses that are capable of holding styling information.

First, change your string resource to use html entities to escape the html tags:

<string name="rights">Copyright © All Rights Reserved %1$d &lt;b> &lt;a href="http://www.example.com/">company name&lt;/a>&lt;/b></string>

Next, obtain a String with the format arguments replaced with the actual values you desire:

String withHtmlMarkup = getString(R.string.rights, currentYear);

Finally, use Html.fromHtml() to parse the html markup:

CharSequence styled = Html.fromHtml(withHtmlMarkup);

Then you can set this styled text to your TextView as normal:

appInfoRights.setText(styled);
appInfoRights.setMovementMethod(LinkMovementMethod.getInstance());

Developer guide: https://developer.android.com/guide/topics/resources/string-resource#FormattingAndStyling

Normally, this doesn't work because the format(String, Object...) and getString(int, Object...) methods strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String), after the formatting takes place.