私は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は重なります。
何か助け?
ありがとう
GoogleはConstraintLayout
の最新リリースで「障壁」の概念を導入しました。これは、この質問に対する答えをXMLで100%解決可能にするのに役立ちます。 ConstraintLayout 1.1.0 beta 1リリースノート を参照してください。ただし、このノートには新しい機能に関する多くの情報は含まれていませんが、新しいものに触れた I/O 2017でのトーク がありました。
新しいソリューションは、GridLayout
のグリッドをバリアで複製することです。左側のTextView
sの右側に垂直バリアがあり、上部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>
更新: 受け入れられた回答 。を参照
GridLayout
をConstraintLayout
で複製する方法は、純粋にXMLで望む方法があるとは思いません。少しのコードでレイアウトを支援したい場合は、ConstraintLayout
をセットアップして、移動可能な垂直ガイドラインを使用してGridLayout
として機能させることができます。
描写するように2列にXMLレイアウトを構築します。左側の列の各TextView
の上部は、右側の列の対応するTextView
の上部に制約されるため、右側のエントリが増加すると、左側のエントリは上下に移動しますまたは高さを減らします。
すべての右側の列ビューは、左側で上記の垂直ガイドラインに拘束されます。 XMLでのこのガイドラインの配置は、作業に適したものでなければなりませんが、実際の配置はコードで行われ、左側の最も広いビューの幅に応じて調整されます。
これはあなたが提起する問題の解決策ですが、一般的な解決策ではありません。以下は、左側の各TextView
の高さが、右側の対応するTextView
の高さ以下であることに依存します。
Android Studioレイアウトエディタでのレイアウトは次のようになります。ガイドラインを右に押して、どのように浮かぶかを示します。コードは画像に続きます。)
これがスクリーンショットです。これがあなたのお役に立てば幸いです。
以下は、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);
}
}
これを試してください。
<?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>
現時点では、1つのConstraintLayout
コンテナだけで実行することは不可能だと思います。今後、Googleがgroup_id
または「グループに合わせて」レイアウトを計算する他の方法。
それまでは、ConstraintLayout
内でConstraintLayout
コンテナーを使用することをお勧めします。これは私がこれをどのように実装したかです:
行を「グリッド」のようにするために、「 ConstraintLayout Chains 」を使用しました。各ConstraintLayout
チェーンの行数は同じでなければなりません。そのため、自動分散は行を正しく整列します。 (使用しない場合は空のままにするか、非表示にすることができます)。