web-dev-qa-db-ja.com

ConstraintLayoutアイテムを2つのアイテムの最後に配置する

垂直に積み重ねられた2つのビューAとBを持つConstraintLayoutがあります。私は、AとBの両方の水平方向の端にある必要がある3番目のビューCを持っています。任意の時点で、AはBよりも広い場合があり、その逆もあるので、制約は1つのビューのみに基づくことはできません。ビューCを通じてこの制約を定義する方法はありますか?

現在、AとBを定義して、

app:layout_constraintEnd_toStartOf="C"

これは機能しますが、Cには開始制約がないため、デザインプレビューは次のような他のプロパティを適切に描画しません。

app:layout_constraintHorizontal_bias="1.0"

別のオプションは、どういうわけかAとBをグループ化することかもしれません。グループ化に関するほとんどの質問はチェーンについて話しますが、これはこの問題を解決するとは思いません。 2つをラップする別のビューを追加することも、ネストされた子を排除することを目的としたConstraintLayoutの目的に反するようです。

編集:以下の例を添付しました:

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

この場合、バイアスが0.5であるため、プレビューには中央の「ビューC」が表示されます。ただし、それらはview_aおよびview_bで定義されているため、開始境界を認識していないため、非常に右に固執します。

ソリューション:

以下は全体の私の最終的なレイアウトです

<?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を試してみました。これも制約レイアウトベータ版の新機能ですが、子供が去ったとマークされたときに調整されません。

Resulting layout

13
Allan W

これは、新しいBarriers機能を使用して簡単に実現できます。

<?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ウォールを構築するようなものです。だから、あなたはそれが「立ち入り禁止」とされている方向に言及する必要があります。私たちの場合はそれが正しいです(view_c)。 barrierDirection属性を使用するだけです。
最後に、view_cが除外ゾーン(layout_constraintLeft_toRightOf="@+id/barrier1")にあることを確認することを忘れないでください。

この機能はConstraintLayoutの1.1.0 beta1リリースでのみ使用できるため、build.gradleファイルにこの行を追加することを忘れないでください。

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


お役に立てれば!

10
Rami Jemli

私はIDE=でこれを試しました、そして私は実行時に動的にそれをするためにいくつかのコードを思いつきました

TextView viewa = (TextView) findViewById(R.id.view_a);
TextView viewb = (TextView) findViewById(R.id.view_b);

ConstraintLayout cl = (ConstraintLayout) findViewById(R.id.constraintLayout);
ConstraintSet cs = new ConstraintSet();
cs.clone(cl);
cs.connect(viewb.getWidth() > viewa.getWidth() ? R.id.view_b : R.id.view_a, ConstraintSet.RIGHT, R.id.view_c, ConstraintSet.LEFT);
cs.applyTo(cl);

これにより、左側の画面からより広いビューが押し出されるので、少し混乱します。たぶん、現時点では理解できないので、それを理解できるでしょう。

0
Eyad Kobatte