I have a ListView
with custom View
where I have a TextView
:
<TextView
android:id="@+id/textViewItemTitle"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="right|center_horizontal"
android:text="title" />
This TextView
contains Hebrew text.
if(!bidi.isRtl(event)){
event = bidi.unicodeWrap(event);
}
holder.title.setText(String.format("%s %s %s", bidi.unicodeWrap(item.getStartTimeNoDate().trim()), event,
bidi.unicodeWrap(item.getDuration().trim())));
Where the first argument is time hh:mm:ss, second (event) is a Hebrew String and third like the first.
The problem: some time the event String contains mixed text in Hebrew and English like abc-אבג
then all the text behave like the the gravity is left (and not right like I defined in the text view), I mean indented to left.
How to solve that?
The accepted answer will do the job when the text is in a TextView
. This is a more general answer, applicable both to the basic/happy scenario and to other, more complicated use cases.
There are situations when mixed-language text is to be used someplace other than inside a TextView
. For instance, the text may be passed in a share Intent
to Gmail or WhatsApp and so on. In such cases, you must use a combination of the following classes:
As quoted in the documentation, these are ...
Utility class[es] for formatting text for display in a potentially opposite-directionality context without garbling. The directionality of the context is set at formatter creation and the directionality of the text can be either estimated or passed in when known.
So for example, say you have a String
that has a combination of English & Arabic, and you need the text to be
then you could achieve this using the unicodeWrap()
method as follows:
String mixedLanguageText = ... // mixed-language text
if(BidiFormatter.getInstance().isRtlContext()){
Locale rtlLocale = ... // RTL locale
mixedLanguageText = BidiFormatter.getInstance(rtlLocale).unicodeWrap(mixedLanguageText, TextDirectionHeuristics.ANYRTL_LTR);
}
This would convert the string into RTL and align it to the left, if even one RTL-language character was in the string, and fallback to LTR otherwise. If you want the string to be RTL even if it is completely in, say English (an LTR language), then you could use TextDirectionHeuristics.RTL
instead of TextDirectionHeuristics.ANYRTL_LTR
.
This is the proper way of handling mixed-direction text in the absence of a TextView
. Interestingly, as the documentation states,
Also notice that these direction heuristics correspond to the same types of constants provided in the
View
class forsetTextDirection()
, such asTEXT_DIRECTION_RTL
.
Update:
I just found the Bidi
class in Java which seems to do something similar. Look it up!
Further references: