In the Android user view, I draw several custom text texts that can be bidirectional. For example, in Hebrew or Arabic mixed with English text or numbers. To draw text, I mainly use the Canvas, TextPaint, and StaticLayout views. The actual code is quite complex and common, but the bit that draws the text looks like this:
TextPaint _paint = getPaint();
Canvas _canvas = ...;
PointF l = locationCenter();
int alignment = getAlignment();
PointF textSize = getTextBounds();
String text = userInputText();
switch (alignment) {
case 0:
_paint.setTextAlign(Paint.Align.CENTER);
l.x += textSize.x / 2.0f;
break;
case 1:
_paint.setTextAlign(Paint.Align.LEFT);
l.x -= 1;
break;
default:
_paint.setTextAlign(Paint.Align.RIGHT);
l.x += (textSize.x + 1);
break;
}
StaticLayout layout = new StaticLayout(text, _paint, (int) Math.ceil(textSize.x + 0.5f), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
_canvas.translate(l.x, l.y);
layout.draw(_canvas);
_canvas.translate(-l.x, -l.y);
LTR RTL, Bidi, . , 0 ( _paint.setTextAlign(Paint.Align.Left), , (= ). 0, BiDi ( RTL), . , Canvas, Paint StaticLayout .
BidiFormatter, :
BidiFormatter.Builder builder = new BidiFormatter.Builder();
builder.stereoReset(true);
android.support.v4.text.BidiFormatter formatter = builder.build();
String text = formatter.unicodeWrap(userInputText());
( ).
, () BiDi ?
, Paint.Align.Left , , .
Android 4.0, 4.2 4.4.
.
, Character.getDirectionality rtl :
public static boolean containsRtlChar(String text) {
for (int i = 0; i < text.length(); i++) {
int c = text.codePointAt(i);
int direction = Character.getDirectionality(c);
if ((direction == Character.DIRECTIONALITY_RIGHT_TO_LEFT) || (direction == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC) || (direction == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING) || (direction == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE))
return true;
}
return false;
}
(
if (containsRtlChars(text)) {
alignment = TextStyle.textAlignLeft;
}
, RTL char, , () .