TextView: Some of the unicode characters are not rendered - android

I am trying to render a simple bullet on my TextView. Here is my code
private static final String DOT = "\u26ab"; //"\u2b24";
helloWorld = (TextView) findViewById(R.id.hello_world);
helloWorld.setText(Html.fromHtml("hi <h1 style='display:inline'>" + DOT+ "</h1> here"));
The unicode character \u2b24 is not rendered correctly below API level 23.
The character \u26ab is rendered correctly however on all API levels.
Any idea why is it happening?

Try this:
private static final String DOT = "•"; // Bullet
Check this wikipedia page or this page for other resources.
//Java --> Html
\u26ab == ⚫
\u2b24 == ⬤

Related

Put emoji code in a string

I am using this emoji library
https://github.com/hani-momanii/SuperNova-Emoji
This library has a custom textview which can render emojis. How do I set text of that textview so it displays emojis ?
For example I tried this and it did not work :
String happy = " Feeling happy U+1F601 ";
emojitextview.setText(happy);
Switch out the 'U+' for '0x':
int unicode = 0x1F601;
String happy = "Feeling happy " + getEmojiByUnicode(unicode);
And put it through a helper function:
public String getEmojiByUnicode(int unicode){
return new String(Character.toChars(unicode));
}
p.s. if it still doesn't work, you may have to set the textView to use a typeface that supports emoji characters
from:
how set emoji by unicode in android textview

HTML String tags are not replaced (Android)

I have the following piece of HTML:
<p>Bla bla bla...</p>
<p><strong>4. others</strong></p>
<p> </p>
It contains a random <p> </p> tag combination which needs to be filtered out in my Android app. I'm using the following Java code for it:
String html = object.get("Content").toString(); // this is the HTML
html = html.replace("<p> </p>", "");
html = html.replace("<p></p>", "");
html = html.replace("<p><span></span></p>", "");
content.setText(Html.fromHtml(html));
However, when I debug and put a break point on the replace functions, it doesn't replace the strings. Now I have useless <p> tags which I don't want. How do I solve this?
It contains a random tag combination which needs to be filtered out in my Android app.
You need to replace it separately. Because replace() function works case-sensitive and sequential strings.
So, Use below code
String html = object.get("Content").toString().trim(); // this is the HTML
html = html.replace("<p>", "");
html = html.replace("</p>", "");
html = html.replace("<span>", "");
html = html.replace("</span>", "");
content.setText(Html.fromHtml(html));
instead of your joint string in replace()
String html = object.get("Content").toString(); // this is the HTML
html = html.replace("<p> </p>", "");
html = html.replace("<p></p>", "");
html = html.replace("<p><span></span></p>", "");
content.setText(Html.fromHtml(html));
You get result as per you want.
Note: But, remember that anytime you want to replace any character/string than just replace it sequential with case-sensitive. because It gives you exact result.
You are doing it in wrong way.
Correct way:
1. Use StringBuffer instead of String.
2. Find index of < and put it in a variable say int startIdx
3. Find index of > and put it in a variable say int endIdx
4. then use delete() of StringBuffer and specify this startIdx and endIdx to delete HTML tag.
This will remove all HTML code from your string.
Ok so as per your comment, this is how you do it
String replaceThis="<p></p>";
int len = replaceThis.length();
StringBuffer buff="your html string from which you want to replace";
int i;
while((i = buff.indexOf(replaceThis)!=-1)
{
buff.delete(i,len-1);
}

SKipping image while converting html text to string android

Iam converting some Html text from a webpage into a String by doing the following
mydescription =Html.fromHtml(data.getBody()).toString();
This is what data.getBody() returns:-
<div><p>​It's great to have great dynamic companies to work with, and NXP is no exception.</p><p><img alt="This is an image of NXP Logo" src="https://anprodstorage.blob.core.windows.net/b75ef288-0381-45c4-a4cd-809097370bec/untitled.png" style="margin:5px;" /><br></p><div><iframe width="560" height="315" src="https://www.youtube.com/embed/I6191gXXGog" frameborder="0"></iframe> </div><p>​<br></p></div>
But within that html text there is a image source as well. When I do the above I get a square image with obj written inside it instead of the image.
This is myDescription

I just want to get the text and not the image.
How do i just get the text and not the image
Try this way,hope this will help you to solve your problem.
String htmlString = "<div><p>​It's great to have great dynamic companies to work with, and NXP is no exception.</p><p><img alt=\"This is an image of NXP Logo\" src=\"https://anprodstorage.blob.core.windows.net/b75ef288-0381-45c4-a4cd-809097370bec/untitled.png\" style=\"margin:5px;\" /><br></p><div><iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/I6191gXXGog\" frameborder=\"0\"></iframe> </div><p>​<br></p></div>";
String first = htmlString.substring(0,htmlString.indexOf("<img"));
String second = htmlString.substring(htmlString.indexOf("/>",htmlString.indexOf("<img"))+2,htmlString.length());
textview.setText(Html.fromHtml(first+second));
use this code:
String clippedBody = htmlString.replaceAll("<img[^>]*?>.*?/[^>]*?>", "");
I advise using libraries, like jsoup when working with HTML (with soup you will be able to get only text by calling Jsoup.parse(html).text())
Haven't tried it myself
private static final Pattern REMOVE_TAGS = Pattern.compile("<img>(\\S+)</img>");
public static String removeTags(String string) {
if (string == null || string.length() == 0) {
return string;
}
Matcher m = REMOVE_TAGS.matcher(string);
return m.replaceAll("");
}
If you want to strip down all the HTML code, then you can use:
replaceAll("\\<[^>]*>","")
For your second question (from Source 2):
// the pattern we want to search for
Pattern p = Pattern.compile("<p>(\\S+)</p>");
Matcher m = p.matcher(string);
// if we find a match, get the group
if (m.find())
{
// get the matching group
String codeGroup = m.group(1);
// print the group
System.out.format("'%s'\n", codeGroup);
}
Source: 1, 2 and 3

libgdx FreeTypeFontGenerator: how to generate a string with TTF font file correctly?

I use following code to generate font in libgdx:
class XFont {
private FreeTypeFontGenerator _generator;
public BitmapFont getFont(String str,int size) {
if (_generator == null) {
_generator = new FreeTypeFontGenerator(Gdx.files.internal("win/msyh.ttf"));
//_generator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/DroidSansFallback.ttf"));
Gdx.app.log(TAG, "generator"+_generator.toString());
}
return _generator.generateFont(size, str, false);
}
}
when I call :
XFont x = new XFront();
x.getFont("iiiis",11);
raise exception:
java.lang.RuntimeException: Key with name 'i' is already in map.
I work with chinese and japanese.
The generateFont() method takes a string containing the unique characters you'd like to be in the generated font. You then use that generated font to draw a string containing those characters - via font.draw(batch, string, x, y).
Note: I'd recommend not generating a new BitmapFont every time you want to draw a String, but instead generate a font with all the characters you will likely use then reuse that BitmapFont.
First, _generator.generateFont(size, str, false) take str as a string that contains all unique characters that you want to generate bitmap font. I preferred use charset for this. Then you should generate a bitmap font just once. Example:
// in your constants
public static final String FONT_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890,./;'[]\\`~!##$%^&*()_+{}|:\"<>?";
// in your resource loading code
FreeTypeFontGenerator fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("myFont.ttf"));
BitmapFont myFont = fontGenerator.generateFont(24, FONT_CHARSET, false);
fontGenerator.dipose(); // remember to dispose the generator after used
The FONT_CHARSET contains all characters in the keyboard, I think it is enough for English texts.

Zero-width line breaking space for Android

Does anyone know if \u200b should be working on Android as a zero width space that functions as a line break if the TextView length is exceeded by the text of the TextView? It appears that only \u0020 is line breaking for me, but I'm not able to figure out how to have a zero width version of it. \u200b is what I expect should work, per the following link, but it only does the zero-width space and doesn't break...and as stated, only \u0020 is line breaking.
http://www.cs.tut.fi/~jkorpela/chars/spaces.html
I've attached the view of an Activity I'm using for testing where U+ is being used in place of \u.
I've also tried using the fromHtml option to see if there is an Html option that works but haven't had any luck with arial.
Here's the test code I'm using
public class TextSpaceActivity extends Activity {
public static void start( Context ctx ) {
ctx.startActivity( new Intent( ctx, TextSpaceActivity.class ) );
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.text_space_activity );
setTitle( "TextSpaceActivity" );
setText( R.id.tsa_txvw_1, "abc\u0020123\u0020xyz\u0020987" );
setText( R.id.tsa_txvw_2, "abc\u200a123\u200axyz\u200a987" );
setText( R.id.tsa_txvw_3, "abc\u200b123\u200bxyz\u200b987" );
}
TextView txvw;
private void setText( int txvwResId, String txt ) {
txvw = (TextView)findViewById( txvwResId );
txvw.setText( txt );
}
}
I don't believe the line-breaking algorithm understands the zero-width line-break, or soft hyphens, or the line- or paragraph-separator characters for that matter. Here's the code from the Android source that decides if there can be a line break here (android.text.StaticLayout, lines 358-366 in the source):
// From the Unicode Line Breaking Algorithm (at least approximately)
boolean isLineBreak = isSpaceOrTab ||
// / is class SY and - is class HY, except when followed by a digit
((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
(j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
// Ideographs are class ID: breakpoints when adjacent, except for NS
// (non-starters), which can be broken after but not before
(c >= CHAR_FIRST_CJK && isIdeographic(c, true) &&
j + 1 < spanEnd && isIdeographic(chs[j + 1 - paraStart], false));
where isSpaceOrTab is defined just above (line 343) as:
boolean isSpaceOrTab = c == CHAR_SPACE || c == CHAR_TAB;
All the CHAR_ constants are plain character constants, so there's nothing like isspace going on. Lines 952-958 in the same file:
private static final char CHAR_FIRST_CJK = '\u2E80';
private static final char CHAR_NEW_LINE = '\n';
private static final char CHAR_TAB = '\t';
private static final char CHAR_SPACE = ' ';
private static final char CHAR_SLASH = '/';
private static final char CHAR_HYPHEN = '-';
Looking at your other comments, I see you're trying to break Chinese correctly. You might not have to do anything special: as the isIdeographic call above hints, it tries to break between two ideographs without inserting spaces. Only the StaticLayout breaker does this: DynamicLayout only uses newline characters, so it will only break correctly on static text.
I'm afraid from my research it looks like you're screwed. My only suggestion for a work-around would be to use a WebView instead of a TextView, and use the superior line-breaking capabilities of the system's web browser instead of the limited implementation TextView offers.
Since Lollipop, \u200b is supported.
This is implemented in StaticLayout with a native call on nLineBreakOpportunities.
Related: I just tested use of the zero-width space character entity ​ as part of an app title, and it is handled as expected when the app's icon is rendered on the desktop by the Android OS.
<string name="app_name">
App​Name​With​Many​Words
</string>
I tried this on Android 5.0; unknown whether it will work in older versions, however.
In your strings.xml:
<string name="sample_string"><![CDATA[abc123<br />xyz987]]></string>
In your Activity:
TextView textView = (TextView) findViewById(R.id.myText);
textView.setText(Html.fromHtml(getResources().getString(R.string.sample_string)));
Hope it helps!
If you only want to control the presentation in a browser, you might try a zero-width inline class in CSS:
.zw { display: inline-block; width: 0; }
Then, in the HTML:
abc<span class="zw"> </span>123

Categories

Resources