Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Supporting RTL locales when drawing in custom views

When I draw in my custom view using the Canvas, is there a simple way to draw for RTL locales without manually inverting coordinate calculations?

As a very contrived example, here is a custom View with the following in onDraw():

int w = getWidth();
int h = getHeight();
canvas.save();

mPaint.setColor(Color.RED);
canvas.drawRect(0, 0, w / 2, h, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawRect(w / 2, 0, w, h, mPaint);

int size = h / 4;
mPaint.setColor(Color.GREEN);
int paddingEnd = ViewCompat.getPaddingEnd(this);
canvas.translate(-paddingEnd, getPaddingTop());
canvas.drawRect(w - size, 0, w, size, mPaint);

canvas.restore();

It appears exactly the same in LTR and RTL layouts:

enter image description here

I know you can flip the Canvas using a Matrix or canvas.scale(), but this is not a viable option for more complicated scenarios, such as drawing text or other Drawables on the Canvas.

What is the best way to accomplish RTL drawing on a Canvas? Do I literally have to calculate inverted values for X-axis coordinates?

like image 567
Karakuri Avatar asked Dec 04 '15 15:12

Karakuri


People also ask

What is RTL support in android?

Supporting different languages goes beyond using locale-specific resources. Some users choose a language that uses right-to-left (RTL) scripts, such as Arabic or Hebrew, for their UI locale.

What is an RTL layout?

An RTL layout is the mirror image of an LTR layout, and it affects layout, text, and graphics. It is also called as 101 rules for Bi-directional UX. When a UI is changed from LTR to RTL (or vice-versa), it's often called mirroring, but it's not just mirroring.

How to set RTL in android?

In your android phone, tap on “Settings” icon. Now tap on developer options and search for “Force RTL layout direction”. Tap on it to enable RTL feature.

What is RTL layout android?

A layout direction can be left-to-right (LTR) or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default language script of a locale.


1 Answers

As far as I could find, there isn't anything in the framework that automatically handles transforming the canvas (for drawing, as in this case) or that handles positioning views (for layout). In other words, I have to do that work myself using View.getLayoutDirection() to determine the layout direction and calculate accordingly. Since most drawing code works with the left position of the object, you can usually do something like

if (isRtl) {
    left = width - shapeWidth - left;
}

where width is the width of the canvas (or the area of the canvas you are drawing in, e.g. if you've already subtracted the amount consumed by left and right padding), and shapeWidth is the shape width. Then you add the shape width to left to get the right value.

A similar approach can be used for laying out child views.

like image 194
Karakuri Avatar answered Nov 10 '22 06:11

Karakuri