Android Hebrew (RTL) Integration
Asked Answered
M

2

7

I'm working on a relatively simple Android app. I want it to have an English version as well as a Hebrew version. (RTL Right to Left Alignment)

I have manually change the alignment to right in layout xml file. When a sentence contains digits (in the middle of it), the digits appear in a mirror view: 29 appears as 92, 21:45 appears as 54:12 and 2,000 appears as 000,2.

Also, when a sentence starts with digits or English characters, they get thrown to the end of the sentence messing it all up.

I think for android version 4.0.3 it supports Hebrew. I have check that in emulator.

So for older versions is there correct way to implement Hebrew? Please help.

Manxman answered 11/6, 2012 at 6:13 Comment(0)
I
24

I think that Android's bidi analysis algorithm has some flaws. Unicode has two invisible, strongly directional characters that might help with these problems:

  • U+200E - left-to-right mark
  • U+200F - right-to-left mark

For the digit order problem, try putting left-to-right marks (U+200E) on both sides of the digit sequence.

Unicode also has the following bidi formatting codes:

  • U+202A - left-to-right embedding
  • U+202B - right-to-left embedding
  • U+202C - pop directional formatting (cancels the previous embedding or override)
  • U+202D - left-to-right override
  • U+202E - right-to-left override

For the problem with English fragments in Hebrew text, it might be as simple as putting a right-to-left mark before the English. (Android's algorithm may be under the impression that the paragraph is left-to-right since the first characters are English.) If that doesn't work, perhaps try surrounding selected text with some combination of formatting codes. (I'd try left-to-right embedding followed by pop directional formatting. I'd also try right-to-left embedding around everything combined with selective explicit right-to-left embeddings.)

The way these are supposed to affect text layout are defined by the Unicode Bidirectional Algorithm Unicode Standard Annex #9. However, if Android's implementation is broken (and I suspect it is), the best you can do is trial-and-error until you get things looking right. Good luck.

EDIT

As far as code is concerned, here's an example of how it might be done in Java:

String text = "גרסה \u200e2.100\u200e זמינה";

In XML, it might be:

<string name="update_available">גרסה &#x200e;2.100&#x200e; זמינה</string>
Immortality answered 12/6, 2012 at 1:25 Comment(15)
you have a grammar mistake in Hebrew - you need to change זמין to זמינהMyopic
Since how it looks like on the code is confusing, can you please tell which character to put on the end and which on the start ?Socman
@androiddeveloper - My suggestion was to put a left-to-right mark (U+200E) on each end of the number. That forces the entire number to be laid out left-to-right. One could also put a left-to-right embedding (U+202A) or left-to-right override (U+202D) at the beginning of the number and a pop directional formatting (U+202C) at the end. That should have the same effect.Immortality
@TedHopp It should work on any kind of text, right? not just numbers... If so, maybe you should have written the code as : String text = '\u200e'+ hebrewText+ '\u200e' ;Socman
@androiddeveloper - It should work for any text that you want laid out left-to-right inside a right-to-left context but isn't (as in OP's examples, but not, as in your suggestion, straightforward Hebrew text). Note, however, that some older versions of Android have poor font support for these codes and they might end up creating a visual mark on the display (even though according to the Unicode standard they are supposed to be invisible). Setting the widget to use a better font that you ship with your app would address this problem if you have to deal with it.Immortality
@TedHopp I don't understand. Why wouldn't the code I wrote work? Also, do you know about RTL layout direction (new from Android 4.2) ? If so, do you know how to set it to preferences' dialogs? Here's a post about it that I wrote: https://mcmap.net/q/1475232/-android-preferencescreen-right-to-leftSocman
@androiddeveloper - The Hebrew text is (presumably) strongly right-to-left. The presence of \u200e at the start will establish a left-to-right base flow (if the base flow isn't already set), but otherwise won't help with the layout of OP's examples where numbers are within a strongly right-to-left context (e.g., hebrewText + "2,000" + hebrewText). The problem there is that the "2,000" is surrounded by right-to-left text on both sides. Surrounding the entire text with \u200e codes won't change the problem behavior OP is trying to deal with.Immortality
@TedHopp oh, sorry about that. here the problem is only with the numbers that are in the middle of Hebrew text, so you need to add this character for every number that exists in the text? like that: String text=hebrewText+'\u200e'+someNumber+'\u200e'+hebrewText; ?Socman
@androiddeveloper - Exactly. This is only necessary to deal with specific problems caused by bugs in some earlier versions of Android. The more recent releases have fixed most (possibly all) of these problems and such tricks are necessary only in rare and complex cases.Immortality
@TedHopp I see. Thank you. I will now add +1 for your comments. Can you please check the link I've written about?Socman
@TedHopp How would you handle notifications and toasts that have mixed Hebrew and English content ? Those always have issues displaying correctly...Socman
@androiddeveloper - I don't know that anything different is needed. Use the bidi formatting characters as needed to correct problems. The good news is that the more recent versions of Android are doing a much better job of this, so I think the problem is going away on its own.Immortality
@TedHopp No, I've searched the APIs. There are no text direction functions for toasts, tickerText, and maybe even notifications (though maybe for notification I just didn't search enough).Socman
@androiddeveloper - I wasn't talking about text direction functions; just text direction formatting codes (left-to-right mark, etc.). For a Toast, note that you can create your own View and pass that in a call to the toast's setView method before calling show(). That way you can set various view attributes, including (at least on more recent Android versions) the view's base layout direction.Immortality
@TedHopp Yes, I see. What about notifications and tickerText? If you wish, you can check this post: https://mcmap.net/q/1027506/-how-to-handle-mixed-rtl-amp-ltr-languages-in-notificationsSocman
E
2

here is an example from my hebrew string xml, Thanks to Ted Hopp's answer:

you need to add '\u200e' before the char that causes you the problem:

<string name="basic_text1">המר על תוצאת המשחק\u200e:</string>

and the result will be:

 :המר על תוצאת המשחק
Equiponderance answered 19/3, 2015 at 8:15 Comment(3)
Do you need to do that on every line with hebrew text?Govea
as far as I can Remember on Runtime you don't need this, but you need to add it in order to see it properly on the graphical layout.Equiponderance
Did you need to install a custom font?Govea

© 2022 - 2024 — McMap. All rights reserved.