Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android RTL layout direction align center issue

I'm developing an Android App that needs to be support Arabic language. (Which should be read from Right To Left). After quick googled the solutions, I figure out android fully support Arabic language natively in API level 17 with the declaration of

android:supportsRtl="true"

in the application tag inside of the AndroidManifest so that I can use the layout mirroring to automatically flip the layout for better right to left reading experience. However, I've noticed there is an issue happening while I use centerInParent in a view that inside of a sub RelativeLayout during the layout mirroring. Below are my codes and expected layout.

<RelativeLayout
    android:background="@color/white"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:padding="20dp">

    <RelativeLayout
        android:background="@drawable/shape_flag_imageview_boarder"
        android:id="@+id/imageLayout"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content">

        <ImageView
            android:id="@+id/image"
            android:layout_height="100dp"
            android:layout_width="100dp"
            android:visibility="invisible" />

        <ProgressBar
            android:id="@+id/progressbar"
            android:layout_centerInParent="true"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content" />

    </RelativeLayout>

    <TextView
        android:id="@+id/text"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:layout_toEndOf="@id/imageLayout"
        android:layout_width="wrap_content"
        android:text="Some text here bla bla bla"
        android:textColor="@color/black" />

</RelativeLayout>

Normal Left to Right Layout

Image above showing the expected result in normal layout direction which is Left to Right. The purpose I wrap the ImageView and ProgressBar together in a sub view is because I want the ProgressBar showing in the middle of the ImageView while the image is loading from the internet. After the I've changed Locale to Arabic, it becomes like Layout out in RTL
As I've try and error and figure out that this is causing by the centerInParent of the ProgressBar. It instead of centering inside the sub view, it align center to the root parent view which is the most outer RelativeLayout. Below is the screen shot of removing centerInParent code from the ProgressBar.

enter image description here

It clearly shows the layout mirroring works good, but the ProgressBar position is not what I'm expected. So I've try to work on centerVertical and centerHorizontal, the result are shown in images below respectively. enter image description hereenter image description here

None of the solutions works, and none of the topic I've searched related to this issue. So I guess this might be a bug from Android library? If anyone knows the issues or solutions, please share to me. Thanks

like image 676
Wai Hong Avatar asked Apr 27 '15 06:04

Wai Hong


2 Answers

I fixed it by adding android:layoutDirection="ltr" into the child RelativeLayout. Basically, it deactivates the RTL formatting for this particular RelativeLayout, and the android:layout_centerInParent="true" behaves correctly again. It solves our particular issue as our particular RelativeLayout contains only centred elements. But this trick should not be used if the Layout contains other elements which have to support correctly RTL, like text views for example. Hope it helps.

like image 138
Lolo06 Avatar answered Sep 19 '22 07:09

Lolo06


This is an RTL layout bug in the Android framework, which only affects Android 4.2 specifically (API 17) and when android:supportsRtl="true" is enabled in AndroidManifest.xml.

It happens when you use a RelativeLayout that contains items positioned with android:layout_centerVertical="true" or android:layout_centerInParent="true".

You can fix it in Java code like this:

View relativeLayout = layoutInflater.inflate(R.layout.my_relative_layout, parent, false);

// Fix RTL layout bug on Android 4.2 (for Arabic and Hebrew mode)
if (Build.VERSION.SDK_INT == 17 &&
       getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
     // Force a left-to-right layout
     relativeLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 }
like image 28
Mr-IDE Avatar answered Sep 18 '22 07:09

Mr-IDE