ListView layout inconsistent rendering with RTL languages (Arabic)

风格不统一 提交于 2019-12-01 16:29:56

问题


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:

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

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>

回答1:


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>



回答2:


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.




回答3:


Try using a Relative Layout for your row items, with the gravity as 'start' and 'end' (instead of 'left' and 'right') to see if that helps.

(If you always want the image to be on a specific side then use left/right instead of start/end)

Also, make sure you have rtl support on in your Manifest file android:supportsRtl=true

https://developer.android.com/guide/topics/manifest/application-element.html




回答4:


Try changing TextView gravity to this: android:gravity="center_vertical|right"




回答5:


If you want to generalise rtl and ltr using the same layout, in my opinion the best way to deal with two ImageViews and make one Visible / Gone according to your need. Something like this:

<?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="match_parent" >

        <ImageView
            android:id="@+id/img_rtl"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="5dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp" />

        <ImageView
            android:id="@+id/img_ltr"
            android:layout_marginBottom="5dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:layout_width="wrap_content"
            android:visibility="gone"
            android:layout_height="wrap_content"
            android:padding="1dp" />

        <TextView
            android:id="@+id/title"
            android:layout_toLeftOf="@id/img_rtl"
            android:layout_toRightOf="@id/img_ltr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:textSize="25sp" >
        </TextView>

</RelativeLayout>

Make img_rtl 'visible' and img_ltr 'gone' in case of arabic texts and opposite in case of english, from your getView method.



来源:https://stackoverflow.com/questions/49696154/listview-layout-inconsistent-rendering-with-rtl-languages-arabic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!