如何在 ConstraintLayout 中部分允许 LTR、RTL 支持

How to Partially Allow LTR, RTL support in a ConstraintLayout

所以在我最近的采访中有人问我,如果在 ConstraintLayout 中有多个 child Views 支持部分 Views LTR 和 RTL 更改和部分Views 的忽略它。喜欢下面的图片:

如您所见,蓝色视图根据视图的布局方向改变它们的方向,但红绿和黄色视图保持相对位置,但根据布局方向对齐它们的(集体)开始和结束不同 View.

我知道您可以简单地通过使用开始和结束属性而不是左和右来设置蓝色 Views。但是,如何保持多彩 Views 的顺序不变,同时将它们与其他 Views 并排放置?同时确保没有比 parent ConstraintLayout.

更深的层次结构

我意识到我在这里可能没有多大意义,我只是想不出另一种方式来表达这个问题。

将多色视图包装在单个视图中,并将该视图作为其他视图约束的父视图。

有趣的问题。我不知道有什么方法可以指定当所有其他部分变为 RTL 时布局的一部分应保留 LTR。我认为您正在寻找仅 XML 的解决方案。

请记住,从左到左、从右到左的约束仍然有效。通常,这些只会被开始到开始和结束到开始的约束所取代。因此,考虑到这一点并对布局做出一些假设,以下工作:

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <View
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="300dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:background="@android:color/darker_gray"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view2"
        android:layout_width="239dp"
        android:layout_height="75dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:background="@android:color/holo_blue_bright"
        app:layout_constraintStart_toEndOf="@+id/view"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/box1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginTop="24dp"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        android:background="@android:color/holo_orange_light"
        app:layout_constraintRight_toLeftOf="@+id/box2"
        app:layout_constraintLeft_toLeftOf="@+id/view2"
        app:layout_constraintTop_toBottomOf="@+id/view2" />

    <View
        android:id="@+id/box2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="24dp"
        android:background="@android:color/holo_red_light"
        app:layout_constraintRight_toLeftOf="@+id/box3"
        app:layout_constraintLeft_toRightOf="@+id/box1"
        app:layout_constraintTop_toTopOf="@+id/box1" />

    <View
        android:id="@+id/box3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="24dp"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        android:background="@android:color/holo_green_light"
        app:layout_constraintRight_toRightOf="@id/view2"
        app:layout_constraintLeft_toRightOf="@+id/box2"
        app:layout_constraintTop_toTopOf="@+id/box2" />

</androidx.constraintlayout.widget.ConstraintLayout>

有一个技巧:必须在水平链中的第一个和最后一个视图上设置layout_constraintHorizontal_chainStyle。设计者也有将 left/right 属性改回 start/end 的倾向。

IRL,我只是将块包装在一个视图组中并完成它。我认为这样更容易维护并且不易损坏。