web-dev-qa-db-ja.com

ConstraintLayoutでGridLayout列の配置を複製しようとしています

私はConstraintLayoutが初めてであり、GridLayoutが提供する同じグリッド動作をConstraintLayoutで複製しようとしています。

具体的には、2列のグリッドを設計します。最初の列の幅は可能な限り狭くする必要がありますが、2番目の列は残りの水平スペースをすべて使用する必要があります。もちろん、2番目の列は最初の列のすぐ右側、または最初の列の最も広いビューに配置する必要があります。

この最後の要件をConstraintLayoutでどのように複製できるかわかりません。最初の列は固定幅でもパーセント幅でもなく、そのビューの最も広い幅である必要があるため、2つの列の間にグリッド線を使用したくありません。

https://Gist.github.com/venator85/499dd82f47b3efbbed7a1e9e1ca1412d では、レイアウトの例と対応するプレビューを準備し、必要なものを実装するGridLayoutを示しています。そのレイアウトでの最初の2つのConstraintLayoutの試行では、C1とD1がB1に、C2とD2がB2に位置合わせされています。 B2がA2より狭い場合、A1とC1は重なります。

何か助け?

ありがとう

15
Venator85

GoogleはConstraintLayoutの最新リリースで「障壁」の概念を導入しました。これは、この質問に対する答えをXMLで100%解決可能にするのに役立ちます。 ConstraintLayout 1.1.0 beta 1リリースノート を参照してください。ただし、このノートには新しい機能に関する多くの情報は含まれていませんが、新しいものに触れた I/O 2017でのトーク がありました。

新しいソリューションは、GridLayoutのグリッドをバリアで複製することです。左側のTextViewsの右側に垂直バリアがあり、上部3行の下にバリアがあります。バリアは、各TextViewに存在するテキストの量に応じてシフトしますが、app:constraint_referenced_idsで指定された位置を常に維持します。本質的に、バリアはフローティングガイドラインのように機能します。このソリューションは、ビデオの内容をサポートするためにコーディングに依存していません。

新しいレイアウトのビデオ は、別のTextViewの内容が変更されたときに維持される各TextViewの望ましい配置を示しています。ビデオは、Android Studio 2.3.2。の設計ツールで作成されました。

そして、バリアを使用した新しいレイアウトのXML:

<?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"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/constrained"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.constraint.Barrier
        Android:id="@+id/barrierVertical"
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:orientation="vertical"
        app:barrierDirection="right"
        app:constraint_referenced_ids="L1, L2, L3, L4" />

    <TextView
        Android:id="@+id/L1"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="L1 *"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R1"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1 R1*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <Android.support.constraint.Barrier
        Android:id="@+id/barrier1"
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L1, R1" />

    <TextView
        Android:id="@+id/L2"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="L2 L2*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier1"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R2"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2 R2*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier1"
        tools:ignore="HardcodedText" />

    <Android.support.constraint.Barrier
        Android:id="@+id/barrier2"
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L2, R2" />

    <TextView
        Android:id="@+id/L3"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="L3 L3 L3*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier2"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R3"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3 R3*"
        app:layout_constraintLeft_toRightOf="@id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier2"
        tools:ignore="HardcodedText" />

    <Android.support.constraint.Barrier
        Android:id="@+id/barrier3"
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:orientation="horizontal"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="L3, R3" />

    <TextView
        Android:id="@+id/L4"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="L4 L4 L4 L4 L4 L4*"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier3"
        tools:ignore="HardcodedText,RtlHardcoded" />

    <TextView
        Android:id="@+id/R4"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:text="R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4 R4*"
        app:layout_constraintLeft_toRightOf="@+id/barrierVertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier3"
        tools:ignore="HardcodedText" />

</Android.support.constraint.ConstraintLayout>
8
Cheticamp

更新: 受け入れられた回答を参照

GridLayoutConstraintLayoutで複製する方法は、純粋にXMLで望む方法があるとは思いません。少しのコードでレイアウトを支援したい場合は、ConstraintLayoutをセットアップして、移動可能な垂直ガイドラインを使用してGridLayoutとして機能させることができます。

描写するように2列にXMLレイアウトを構築します。左側の列の各TextViewの上部は、右側の列の対応するTextViewの上部に制約されるため、右側のエントリが増加すると、左側のエントリは上下に移動しますまたは高さを減らします。

すべての右側の列ビューは、左側で上記の垂直ガイドラインに拘束されます。 XMLでのこのガイドラインの配置は、作業に適したものでなければなりませんが、実際の配置はコードで行われ、左側の最も広いビューの幅に応じて調整されます。

これはあなたが提起する問題の解決策ですが、一般的な解決策ではありません。以下は、左側の各TextViewの高さが、右側の対応するTextViewの高さ以下であることに依存します。

Android Studioレイアウトエディタでのレイアウトは次のようになります。ガイドラインを右に押して、どのように浮かぶかを示します。コードは画像に続きます。)

enter image description here

これがスクリーンショットです。これがあなたのお役に立てば幸いです。

enter image description here

以下は、ConstraintLayoutを使用したレイアウトです。 (最初の投稿以降、左の列で右に折り返すように更新されました。)

constrained.xml

<?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"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/constrained"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.constraint.Guideline
        Android:id="@+id/guideline"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        app:layout_constraintGuide_begin="257dp" />

    <TextView
        Android:id="@+id/L1"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="0dp"
        Android:text="A1 A1 A1 A1 A1*"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="wrap"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/L2"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="0dp"
        Android:layout_marginTop="0dp"
        Android:text="B1 B1 B1 B1 B1*"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        app:layout_constraintTop_toTopOf="@+id/R2"
        app:layout_constraintWidth_default="wrap"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/L3"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="0dp"
        Android:layout_marginTop="0dp"
        Android:text="A2 A2 A2 A2*"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        app:layout_constraintTop_toTopOf="@+id/R3"
        app:layout_constraintWidth_default="wrap"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/L4"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="0dp"
        Android:layout_marginTop="0dp"
        Android:text="B2 B2 B2 B2 B2*"
        app:layout_constraintHorizontal_bias="0.02"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        app:layout_constraintTop_toTopOf="@+id/R4"
        app:layout_constraintWidth_default="wrap"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R1"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:text="C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1*"
        app:layout_constraintLeft_toRightOf="@id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R2"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:text="D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 D1*"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/R1"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R3"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:text="C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2*"
        app:layout_constraintLeft_toRightOf="@id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/R2"
        tools:ignore="HardcodedText" />

    <TextView
        Android:id="@+id/R4"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:text="D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2 D2*"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/R3"
        tools:ignore="HardcodedText" />

</Android.support.constraint.ConstraintLayout>

ガイドラインの場所を調整するActivityは次のとおりです。

MainActivity.Java

package com.example.layout2;

import Android.os.Bundle;
import Android.support.constraint.ConstraintLayout;
import Android.support.constraint.Guideline;
import Android.support.v7.app.AppCompatActivity;
import Android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Guideline mGuideline;
    private ConstraintLayout mConstraintLayout;
    private TextView L1;
    private TextView L2;
    private TextView L3;
    private TextView L4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.constrained);
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.constrained);
        mGuideline = (Guideline) findViewById(R.id.guideline);
        L1 = (TextView) findViewById(R.id.L1);
        L2 = (TextView) findViewById(R.id.L2);
        L3 = (TextView) findViewById(R.id.L3);
        L4 = (TextView) findViewById(R.id.L4);
        // We will adjust the location of the guideline after layout is completed.
        mConstraintLayout.post(new Runnable() {
            @Override
            public void run() {
                moveGuideline();
            }
        });
    }

    public void moveGuideline() {
        ConstraintLayout.LayoutParams params;

        params = (ConstraintLayout.LayoutParams) mGuideline.getLayoutParams();
        // Find the widest TextView in the left column...
        params.guideBegin = Math.max(Math.max(L1.getWidth(), L2.getWidth()),
                Math.max(L3.getWidth(), L4.getWidth()));
        // ... and set the guideline to the right of the widest one.
        mGuideline.setLayoutParams(params);
    }
}
2
Cheticamp

これを試してください。

<?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"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="horizontal">


    <TextView
        Android:id="@+id/textView5"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="8dp"
        Android:layout_marginTop="8dp"
        Android:text="A1 A1 A1 A1 "
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        Android:id="@+id/textView8"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:layout_marginTop="8dp"
        Android:text="C1 C1 C1 C1 "
        app:layout_constraintHorizontal_bias="0.506"
        app:layout_constraintLeft_toRightOf="@+id/textView5"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        Android:id="@+id/textView9"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:layout_marginTop="8dp"
        Android:text="B1 B1 B1 B1 "
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/textView8"
        app:layout_constraintTop_toBottomOf="@+id/textView8" />

    <TextView
        Android:id="@+id/textView10"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:layout_marginTop="8dp"
        Android:text="D1 D1 D1 D1 "
        app:layout_constraintHorizontal_bias="0.506"
        app:layout_constraintLeft_toRightOf="@+id/textView5"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView5" />

</Android.support.constraint.ConstraintLayout>

このようなもの。 enter image description here

2
shekhar g h

現時点では、1つのConstraintLayoutコンテナだけで実行することは不可能だと思います。今後、Googleがgroup_idまたは「グループに合わせて」レイアウトを計算する他の方法。

それまでは、ConstraintLayout内でConstraintLayoutコンテナーを使用することをお勧めします。これは私がこれをどのように実装したかです:

enter image description hereenter image description here

行を「グリッド」のようにするために、「 ConstraintLayout Chains 」を使用しました。各ConstraintLayoutチェーンの行数は同じでなければなりません。そのため、自動分散は行を正しく整列します。 (使用しない場合は空のままにするか、非表示にすることができます)。

xml Gist

0
Amir Uval