Android RTL布局方向居中对齐问题

5
我正在开发一个Android应用程序,需要支持阿拉伯语言(应该从右到左阅读)。在快速搜索了解解决方案后,我发现android从API 17版本开始原生支持阿拉伯语言,并且在AndroidManifest文件中的应用标签中声明

android:supportsRtl="true"

以便使用布局镜像自动翻转布局,获得更好的从右到左阅读体验。但是,在布局镜像中使用centerInParent设置子RelativeLayout视图时出现问题。以下是我的代码和预期的布局。

<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>

正常的从左到右布局

上图显示了从左到右的正常布局方向下的预期结果。我将ImageView和ProgressBar一起包装在一个子视图中的目的是,当从互联网加载图像时,我希望ProgressBar显示在ImageView的中间位置。但是,当我将Locale更改为阿拉伯语后,它变成了如下所示: RTL布局
经过尝试和错误,我发现这是因为进度条的centerInParent属性导致的。它不是居中对齐在子视图内部,而是在最外层RelativeLayout的根父视图中心对齐。下面是移除了进度条的centerInParent代码的截图。

输入图像描述

这清楚地显示了布局镜像效果良好,但ProgressBar的位置不是我期望的。因此,我尝试处理centerVertical和centerHorizontal属性,分别显示如下所示的结果图片。 输入图像描述 输入图像描述

没有一个解决方案能够解决问题,我搜索的主题也没有相关的信息。因此,我猜测这可能是Android库中的一个错误?如果有人知道解决方案或问题,请与我分享。谢谢。


你问题的至少一部分是你没有完全指定任何东西应该放在哪里 - 外部相对布局中的任何内容都没有与父级对象对齐。因此,我不奇怪它无法正确地布局。 - Gabe Sechan
1
你正在定位进度条的父RelativeLayout没有固定的高度和宽度,这可能会导致意想不到的结果。 - TheLittleNaruto
我不知道为什么它只在RTL的情况下无法工作。但是它在LTR的情况下也不应该工作。因为这就是RelativeLayout的工作方式。我们将每个视图相对于RelativeLayout中的其他视图放置,并且在这种情况下,它应该具有固定的高度和宽度。 - TheLittleNaruto
你尝试过在ProgressBar中设置android:gravity="center"吗? - zdd
你可以在RelativeLayout中使用wrap-content。但是当你想把任何视图相对于父布局放置,并且父布局具有固定的高度和宽度时,它的效果更加完美。^^ @GabeSechan - TheLittleNaruto
显示剩余7条评论
3个回答

9
我通过在子RelativeLayout中添加android:layoutDirection="ltr"来解决了这个问题。基本上,它取消了此特定RelativeLayout的RTL格式,并且android:layout_centerInParent="true"再次正确地运行。它解决了我们特定的问题,因为我们的RelativeLayout只包含居中元素。但是,如果布局包含其他必须正确支持RTL的元素,例如文本视图,则不应使用此技巧。希望能够帮到你。

4
这是 Android 框架中RTL布局的一个错误,它仅影响Android 4.2版本(API 17),并且启用了 AndroidManifest.xml 中的 android:supportsRtl="true"。
当你使用 RelativeLayout 并且其中包含使用 android:layout_centerVertical="true" 或 android:layout_centerInParent="true" 属性定位的项目时,就会出现此问题。
你可以用以下 Java 代码来修复它:
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);
 }

2

让我告诉你正确的答案,看一下你的RelativeLayout(id:imageLayout),它的宽度是wrap_content,而你的ProgressBar(id:progressbar)添加了一个属性android:layout_centerInParent="true"。这意味着父元素不限制宽度,子元素也想要居中,所以父元素会被拉伸。


这对我有用,我必须指定相对布局的宽度。 - Ankit Dubey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接