Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView layout inconsistent rendering with RTL languages (Arabic)

I have simple ListView with ArrayAdapter which is working just fine. The problems start with RTL language (Arabic in this case).

When you open it for the first time, everything looks ok:

enter image description here

But after scrolling down and back up, some items appears to be rendered incorrectly:

enter image description here

The code is straightforward. Note that if I do not REUSE view and instead inflate it unconditionally every time (see the commented line below), the issue is GONE. But this is obviously not right, I want to REUSE items for better performance and smooth scrolling.

Please also note that I have multiple ListViews in the app, and all of them shows this kind of incorrect rendering in Arabic. For this question I picked up the simplest case when I just set text and icon for every list item.

Please advice. The portion of code of my implementation of ArrayAdapter:

    public class PagesListAdapter extends ArrayAdapter<IPageRef> {

        ...

        public View getView(int position, View convertView, @NonNull ViewGroup parent) {

            final IPageRef b = getItem(position);
            View row = convertView == null ? mInflater.inflate(R.layout.lang_item, parent, false) : convertView;
            //View row = mInflater.inflate(R.layout.wordlist_item, parent, false);

            TextView title = row.findViewById(R.id.title);
            ImageView img = row.findViewById(R.id.img);

            ... // (setting the title & img properties)

            return row;
        }
    }

lang_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/img"
        android:layout_marginBottom="5dp"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"
        android:layout_width="50dp"
        android:layout_height="38dp"
        android:padding="1dp"
        />

    <TextView
        android:id="@+id/title"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:textSize="25sp" >
    </TextView>

</LinearLayout>
like image 254
Mike Keskinov Avatar asked Apr 06 '18 15:04

Mike Keskinov


People also ask

Should form inputs be left-aligned in RTL layout?

In this case, the icon’s position should be flipped in the RTL layout. Some form inputs should remain left-aligned in RTL — for example, email and mobile-number inputs. It's worth noting that if the placeholder content is in Arabic or other RTL language, then the placeholder should be aligned to the right.

How does the system choose an RTL image?

The system chooses an image named file.layoutdir-rtl.png when the app runtime language (see Understand user profile languages and app manifest languages) is set to an RTL language. This approach may be necessary when some part of the image is flipped, but another part isn't.

Is the default page direction LTR or RTL?

Over 292 million people around the world speak Arabic as their first language. Arabic (al-Arabiyyah, pronounced /al ʕarabijja/, /ʕarabiː/) is my native language, and I sometimes build websites that need to support both left-to-right (LTR) and right-to-left (RTL) styles. The default page direction in CSS is LTR.

What is the correct order of icons in RTL?

For a tabs component in LTR, the icons would be to the left of the label. In RTL, these should be flipped. For a horizontal card, the order of the image and the text should be flipped in RTL.


Video Answer


3 Answers

change your layout to:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:paddingBottom="5dp"
    android:paddingTop="5dp">

    <ImageView
        android:id="@+id/img"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:layout_width="50dp"
        android:layout_height="38dp"
        android:padding="1dp"
        />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/img"
        android:textSize="25sp" />

</RelativeLayout>
like image 52
Mehran Jafari Avatar answered Oct 13 '22 05:10

Mehran Jafari


To support RTL alignment you first need to add android:supportsRtl="true" to the <application> element in your manifest file.

Major thing:-

  • If your app only supports API ≥ 17, replace all the layout_marginLeft/layout_marginRight/paddingLeft/paddingRight or any other Left and Right layout property with Start and End equivalent. For example android:paddingLeft will be replaced with android:paddingStart.
  • If your app supports API<17 then instead of replacing the Left and Right layout properties, add their Start and End layout property equivalent alongside.

Or you can just do for all layouts using Android Studio > Refactor > Add RTL support where possible…

For more references on RTL follow this article for drawables as well here It will surely solve your problem using each step.

like image 31
Karan sharma Avatar answered Oct 13 '22 04:10

Karan sharma


Try manually setting the direction based on configuration (that is quite reliably updated based on device language) by adding rowView.setLayoutDirection(getContext().getResources().getConfiguration().getLayoutDirection()); in the getView of your ListAdapter.

From: ListView's first entry always incorrect for RTL

This solved my problem that was similar to your.

like image 20
Guido Mocha Avatar answered Oct 13 '22 05:10

Guido Mocha