Unicode characters not displayed in TextView.setText

It could be done in such a simple way:

str.replace("uoo26","&");

Unfortunately, you just can't do it that way from strings.xml AFAIK.

You're left doing one of two things.

  • Adding the Unicode character within java to the String in the XML file:

    String str = "\u00A9" + getContext().getString(R.string.your_string);
    
  • Entering the text as HTML in java:

    yourTextView.setText(Html.fromHtml("your chars"));
    

Hope this is useful.


The accepted answer is correct but Html.fromHtml is deprecated now. So you'll need to use:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        textView.setText(Html.fromHtml(user.getInput(), Html.FROM_HTML_MODE_LEGACY));
    } else {
        textView.setText(Html.fromHtml(user.getInput()));
    }

I had problems trying to display Unicode character from a custom font that were mapped in the Unicode private area. This is a common area where fonts like MaterialDesign and FontAwesome map their icon font characters. Just for clarity I was testing this on an android version 4.4.2 so maybe this is not an issue on later versions (but probably is). I had tried all combinations of "\uF151", &#xF151, and I also tried the Html.fromHtlm. None of these techniques worked to properly display the characters in the Unicode private area. If I keep myself to the range \u00xx, they all worked fine for the fonts that had Unicode codes in those locations. (The two fonts I've mentioned don't have any symbols mapped to those point locations)

In examining the font using Microsoft's Character Map I noticed that the characters in the Unicode private area space where not showing up when I had the Windows-English character set chosen for the fonts. The characters would show up if I selected the Unicode character set; and in the case of the Material Design font if I selected the Japanese character set.

What I did to get the character to display on the in TextView was to change the Locale to Japanese, call setText on the Textview object passing it the correct private area unicode value and the character then displayed correctly. So here's the code I used to set icon font symbol and then revert back to English:

    TextView tv = (TextView)findViewById(R.id.myTextViewObject);
    Typeface tf =  Typeface.createFromAsset(this.getAssets(), "material_design.ttf");
    tv.setTypeface(tf);
    String x = "\uE693";

    tv.setText(x);
    setDefaultLocale(getApplicationContext(),"en");
    tv.append("hello");

And here's the code for the setDefaultLocale method:

public static void setDefaultLocale(Context context, String locale) {
    Locale locJa = new Locale(locale.trim());
    Locale.setDefault(locJa);

    Configuration config = new Configuration();
    config.locale = locJa;

    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

    locJa = null;
    config = null;
}

In the case of FontAwesome, you have to select the Tradition Chinese character set to get access to the unicode private area code points.

You might ask, why I didn't select the "Unicode" character set? The character set that android uses is based on the current locale and I couldn't find a way to select unicode as the current locale. In addition, I couldn't find a way to map the private area unicodes into my existing Locale. I also can't tell you whether this is a issue on how these True Type Fonts where constructed or whether this is an Android issue (albeit I think there should have been a why to map the private area code for use in your existing locale) What I have learned is that all Unicode code points are mapped into all language locales for the same font. That's the thing that I think confuses a lot of people about fonts that support unicode. The windows character map was a useful tool for me in determining which character points are mapped into which character set.

Tags:

Android