RTL issue in string containing English, Hebrew and digits in Android (Java) - android

I have an issue when mixing in one string English, Hebrew and digits.
The order of digits next to Hebrew is getting reversed, no matter what order I make - fist digit and then text, of first text and then Hebrew - it's getting reversed to: on the left digit, on the right text.
My text example is:
String leftPart = "10 gr";
int numder = 8;
String hebrewText = "כפות";
String rightPart = hebrewText + " " + number;
String finalString = leftPart + " · " + rightPart; //10 gr · כפות 8
I want to display the digit 8 in the end of this string, after the Hebrew word, not before it, but I'm unable to do it even here...it's getting reversed because of the English text in the begging.
Even if I change the order to:
String rightPart = number + " " + hebrewText ;
the result is the same...
Any ideas? It's looks like something simple that I'm missing

A tip for forcing English to be shown nicely when mixed with Hebrew:
Wrap the English (or numbers) words with LRI and PDI (check here: https://unicode.org/reports/tr9/ ) .
For example, instead of these (first word is in English) :
<string name="test">ABC היא האפליקציה הכי טובה</string>
<string name="test2">%1$s היא האפליקציה הכי טובה</string>
Use these:
<string name="test">\u2066ABC\u2069 היא האפליקציה הכי טובה</string>
<string name="test2">\u2066%1$s\u2069 היא האפליקציה הכי טובה</string>
Other useful ones can be found here:
https://stackoverflow.com/a/10989502/878126

Nothing is screwing up here, this is actually correct behavior. The number is coming after the end of the hebrew word- the end of the hebrew word is on the left. What you seem to want is for the number to come before the hebrew word. But when you combine it with english like that it doesn't know tht the number is supposed to be bound to the hebrew part and not the english part, so putting it before the hebrew doesn't work either.
I'd suggest putting the number before the hebrew part and wrapping the number and hebrew text in unicode right to left mark characters, to tell it explicitly the 8 is part of the right to left text.
Alternatively you could put the number after the hebrew text but use an rtl mark before the hebrew and a ltr mark after. Which is probably a slightly better way of doing things overall if you want more complex embedding elsewhere.

Related

How can I find Android TextView number of characters per word?

How can I find how many characters are there in each word of a TextView in Android. I want to set few words of my TexView to bold type. So for instance if the text view has a text "Happy Coding, Fellow Coders". I would like to set "Coding" & "Coders" to bold type.
Try this solution. It contains counting words based on the comma, colon or semicolon and dot characters :
String str = "Happy Coding, Fellow Coders";
String[] strArr = str.split(",| |.");
Log.e("TAG", "split String: " + strArr);
If you want to split only from whitespaces, then use :
.split("\\s+") instead of .split(" ")
Then you can simply use the loops to count the characters of every words.

Numbers inside TextView getting reversed when formatted in RTL

Numbers inside TextView are getting reversed when formatted in RTL.
When numbers are at the end of a text inside a TextView they getting reversed. How can I solve this programmatically?
As an example, the numbers below are reversed:
They should be displayed like:
The misunderstand:
Digits in RTL languages like ARABIC should be written from RTL with the arabic digits to avoid any problems i.e: "تم إرسال رسالة نصية للرقم ١٢٣٤" Note that I wrote "رسالة نصية" NOT "SMS رسالة".
The problem and it's solution:
Mixing more than one direction languages required more steps, you need to tell the system "hey this is RTL word, add as it to sequence".
So you may need to do this implicitly, i.e:
\u200f + تم إرسال رسالة نصية إلى + number
Consider StringBuilder: It's very painful for developer to develop something for RTL language using plus(+) notation, this much confusing and error prone.
A better way:
builder.append("\u061C").append(" تم إرسال رسالة نصية لـ").append("\u200E").append("+0123456789")
Consider BidiFormatter: Utility class for formatting text for display in a potentially opposite-directionality context without garbling
Example:
String text = "{0} تم إرسال رسالة نصية لـ ";
String phone = BidiFormatter.getInstance().unicodeWrap("+961 01 234 567");
String result = MessageFormat.format(text,phone);
Now, result will be formatted properly.
More examples on how BidiFormatter work.
If you want to prevent the reversing of numbers for TextView when formatted in RTL, just specify android:textDirection="ltr" property for that specific TextView inside XML file. It will display number in the usual order.
Try this out
android:supportsRtl="false" in manifest file
and android:gravity="start" in your layout.
set the textview gravity to start
android:gravity="start"

How to remove hyphen from TextUtils.split(line, "-")?

I found a dictionary sample in GitHub that I am currently experimenting with. The sample database used hyphen between the searched word and the word's meaning. So something like this.
abbey - n. a monastery ruled by an abbot
I looked into the dictionary database java file and found the following code:
String[] strings = TextUtils.split(line, "-");
I have my own database that translates Korean words to English. However I didn't use hyphen while creating it. So is there a way to not use hyphen or any other symbols but simply spaces? Also this is part of an android app.
Edit- An example of my own dictionary would be something like
abbey a monastery ruled by an abbot
Edit-
The problem here is that the old code only differentiates and recognizes the words and the meaning only if they are separated by hyphen. How do I make this so it works with spaces alone.
To remove a character in a String use String.replace
String newString = line.replace("-","");
To replace with a space simply use
String newString = line.replace("-"," ");
String mystring = mystring 1.replace("_"," "); if you want space give space.
As I understand it, you want to split your String to get the output like
abbey - n. a monastery ruled by an abbot
[abbey][n. a monastery ruled by an abbot]
You can use String.split(String, int) to force the number of split.
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times
Let's use it like :
String[] array = s.split(" ", 2);
This will split your String on the regex " " but will limit the size of the output to 2 cells. So it will only split once, put the left part on the first cell and the right part on the second cell.
Without this limit argument, the method would keep split the right part again using a bigger array.
Note: this will be a problem if your word is a sentence in the left part.

What are my options for displaying characters that Android can't?

I discovered today that Android can't display a small handful of Japanese characters that I'm using in my Japanese-English dictionary app.
The problem comes when I attempt to display the character via TextView.setText(). All of the characters below show up as blank when I attempt to display them in a TextView. It doesn't appear to be an issue with encoding, though - I'm storing the characters in a SQLite database and have verified that Android can understand the characters. Casting the characters to (int) retrieves proper Unicode decimal escapes for all but one of the characters:
String component = cursor.getString(cursor.getColumnIndex("component"));
Log.i("CursorAdapterGridComponents", "Character Code: " + (int) component.charAt(0) + "(" + component + ")");
I had to use Character.codePointAt() to get the decimal escape for the one problematic character:
int codePoint = Character.codePointAt(component, 0);
I don't think I'm doing anything wrong, and as String's are by default UTF-16 encoded, there should be nothing preventing them from displaying the characters.
Below are all of the decimal escapes for the seven problematic characters:
⺅ Character Code: 11909(⺅)
⺌ Character Code: 11916(⺌)
⺾ Character Code: 11966(⺾)
⻏ Character Code: 11983(⻏)
⻖ Character Code: 11990(⻖)
⺹ Character Code: 11961(⺹)
𠆢 Character Code: 131490(𠆢)
Plugging the first six values into http://unicode-table.com/en/ revealed their corresponding Unicode numbers, so I have no doubt that they're valid UTF-8 characters.
The seventh character could only be retrieved from a table of UTF-16 characters: http://www.fileformat.info/info/unicode/char/201a2/browsertest.htm. I could not use its 5-character Unicode number in setText() (as in "\u201a2") because, as I discovered earlier today, Android has no support for Unicode strings past 0xFFFF. As a result, the string was evaluated as "\u201a" + "2". That still doesn't explain why the first six characters won't show up.
What are my options at this point? My first instinct is to just make graphics out of the problematic characters, but Android's highly variable DPI environment makes this a challenging proposition. Is using another font in my app an option? Aside from that, I really have no idea how to proceed.
Is using another font in my app an option?
Sure. Find a font that you are licensed to distribute with your app and has these characters. Package the font in your assets/ directory. Create a Typeface object for that font face. Apply that font to necessary widgets using setTypeface() on TextView.
Here is a sample application demonstrating applying a custom font to a TextView.

How to view a Georgian language string in a TextView?

If a TextView has a georgian text, I see only spaces.
i.e
String georgString = "("+"სახლი ქუჩის ბოლოში"+")";
I see:
"( )"
If a TextView has a georgian text, I see only spaces.
I found quick solution. You need to add your gregorian text into strings.xml and then it will work.
<string name="test">(სახლი ქუჩის ბოლოში)</string>
// an usage
textView.setText(getString(R.string.test));
(I just tested it and it works. Probably if you are assigning text directly there is problem with encoding but with an usage of resources you don't have to deal with it). Let me know.

Categories

Resources