将ConstraintLayout项对齐到两个项的末尾 [英] Align ConstraintLayout item to be at the end of two items

查看:44
本文介绍了将ConstraintLayout项对齐到两个项的末尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ConstraintLayout,其中两个视图A和B垂直堆叠.我有第三个视图C,它必须水平到A和B的尽头.在任何给定的点上,A可能比B宽,反之亦然,因此约束不能仅基于一个视图.有没有一种方法可以通过视图C定义此约束?

I have a ConstraintLayout with two views A and B that are stacked vertically. I have a third view C which needs to be to the end of both A and B horizontally. At any given point, A may be wider than B or vice versa, so the constraint cannot only be based on one view. Is there a way of defining this constraint through view C?

当前,我可以定义A和B以便

Currently, I can define A and B so that

app:layout_constraintEnd_toStartOf="C"

这确实有效,但是由于C中没有开始约束,因此设计预览将无法正确绘制其他属性,例如

This does work, but since there is no start constraint in C, the design preview will not properly draw other properties such as

app:layout_constraintHorizontal_bias="1.0"

另一个选择可能是以某种方式将A和B分组.关于分组的大多数问题都涉及链,我认为这并不能解决这个问题.添加另一个视图来包装这两个视图似乎也违反了ConstraintLayout的目的,ConstraintLayout的目的是消除嵌套的子代.

Another option may be to somehow group A and B. Most questions on grouping talk about chains, which I don't think resolves this issue. Adding another view to wrap the two also seems to defeat the purpose of a ConstraintLayout, which is meant to eliminate nested children.

我在下面附有一个示例:

I have an attached an example below:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/view_c"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:text="View C"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

    <TextView
        android:id="@+id/view_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="View A"
        app:layout_constraintBottom_toTopOf="@id/view_b"
        app:layout_constraintEnd_toStartOf="@id/view_c"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_goneMarginBottom="16dp" />

    <TextView
        android:id="@+id/view_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="View B"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/view_c"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view_a" />

</android.support.constraint.ConstraintLayout>

在这种情况下,预览的中间位置应显示"View C",因为其偏差为0.5.但是,它不知道在view_a和view_b中定义的起始边界,因此坚持在最右边.

In this case, the preview should show "View C" somewhere in the middle since its bias is 0.5. However, it does not know its starting bound as they are defined in view_a and view_b, and therefore sticks to the very right.

解决方案:

下面是我整体的最终布局

Below is my final layout in its entirety

<?xml version="1.0" encoding="utf-8"?>

<!--due to animations, we need a wrapper viewgroup so our changes will stick-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/selectableItemBackground"
    android:baselineAligned="false"
    android:clipToPadding="false"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:orientation="horizontal"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/kau_pref_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--As per Android N, icons (24dp) are aligned to the left rather than centered-->

        <ImageView
            android:id="@+id/kau_pref_icon"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_marginBottom="4dp"
            android:layout_marginTop="4dp"
            android:contentDescription="@string/kau_pref_icon"
            android:paddingEnd="32dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.5"
            tools:layout_editor_absoluteX="0dp" />

        <TextView
            android:id="@+id/kau_pref_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:ellipsize="marquee"
            android:textAppearance="?android:attr/textAppearanceListItem"
            android:textColor="?android:attr/textColorPrimary"
            app:layout_constraintBottom_toTopOf="@+id/kau_pref_desc"
            app:layout_constraintEnd_toStartOf="@+id/kau_pref_inner_frame"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintStart_toEndOf="@id/kau_pref_icon"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_goneMarginBottom="16dp"
            tools:layout_editor_absoluteX="-175dp" />

        <TextView
            android:id="@id/kau_pref_desc"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:ellipsize="end"
            android:maxLines="10"
            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
            android:textColor="?android:attr/textColorSecondary"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@id/kau_pref_inner_frame"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintStart_toEndOf="@id/kau_pref_icon"
            app:layout_constraintTop_toBottomOf="@id/kau_pref_title"
            tools:layout_editor_absoluteX="-175dp" />

        <android.support.constraint.Barrier
            android:id="@+id/kau_pref_barrier"
            android:layout_width="1dp"
            android:layout_height="wrap_content"
            app:constraint_referenced_ids="kau_pref_title,kau_pref_desc"
            app:barrierDirection="end"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

        <LinearLayout
            android:id="@id/kau_pref_inner_frame"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:gravity="center_vertical|end"
            android:orientation="horizontal"
            android:paddingStart="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toEndOf="@id/kau_pref_barrier"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.5"
            tools:layout_editor_absoluteX="1dp" />

    </android.support.constraint.ConstraintLayout>

</LinearLayout>

有标题和描述,内部内容必须位于两个视图的末尾.我还尝试了Group,它在约束布局Beta中也是新功能,但是当孩子被标记为已离开时,它不会进行调整.

There is a title and a description, and the inner content must be to the end of both views. I've also tried Group, which is also new in the constraint layout beta, but it doesn't adjust when a children is marked as gone.

推荐答案

使用新的Barriers功能可以轻松实现.

This can be easily achieved using the new Barriers feature.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/view_c"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="View C"
        app:layout_constraintLeft_toRightOf="@+id/barrier1"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier1"
        android:layout_width="1dp"
        android:layout_height="wrap_content"
        app:barrierDirection="right"
        app:constraint_referenced_ids="view_a, view_b"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/view_a"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="View A"
        app:layout_constraintBottom_toTopOf="@id/view_b"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_goneMarginBottom="16dp" />

    <TextView
        android:id="@+id/view_b"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="View B"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view_a" />

</android.support.constraint.ConstraintLayout>

如何使用壁垒?

障碍就像建立一个保护" constraint_referenced_ids中提到的视图的HUUUUGE WALL.因此,您必须提及它应该保持在哪个方向",在我们的情况下,这是正确的(view_c).只需使用barrierDirection属性.
最后,不要忘了确保view_c位于禁止进入区域(layout_constraintLeft_toRightOf="@+id/barrier1").

How to use Barriers ?

Barriers are like building a HUUUUGE WALL that "protects" the views mentioned in constraint_referenced_ids. So, you have to mention which direction it's "supposed to keep out" which in our case is the right (view_c). Just use the barrierDirection attribute.
Finally, don't forget to make sure that view_c is in the keep out zone (layout_constraintLeft_toRightOf="@+id/barrier1").

由于此功能仅在ConstraintLayout的1.1.0 beta1版本中可用,因此请不要忘记将此行添加到build.gradle文件中.

As this feature is available only in the 1.1.0 beta1 release of ConstraintLayout, don't forget to add this line to your build.gradle file.

compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1'


希望这会有所帮助!


Hope this helps!

这篇关于将ConstraintLayout项对齐到两个项的末尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆