Пытается реплицировать выравнивание столбцов GridLayout с помощью ConstraintLayout

Я новичок в ConstraintLayout, и я пытаюсь воспроизвести то же поведение сетки, которое предлагает GridLayout с помощью ConstraintLayout.

В частности, я хочу создать сетку с двумя столбцами. Ширина первой колонки должна быть как можно более узкой, а вторая колонка должна занимать все оставшееся горизонтальное пространство. Конечно, второй столбец должен быть справа от первого столбца, а точнее, до самого широкого вида в первом столбце.

Я не знаю, как я могу воспроизвести это последнее требование с помощью ConstraintLayout. Я не хочу использовать Gridline между двумя столбцами, потому что первый столбец не должен иметь фиксированную или процентную ширину, а быть таким же широким, как и самый широкий его вид.

На https://gist.github.com/venator85/499dd82f47b3efbbed7a1e9e1ca1412d я подготовил пример макета и соответствующий предварительный просмотр, показывая GridLayout, который реализует то, что я хочу. Первые две попытки ConstraintLayout в этом макете показывают, что C1 и D1 выровнены с B1, а C2 и D2 – в B2. Когда B2 уже, чем A2, A1 и C1 будут перекрываться.

Любая помощь?

благодаря

Solutions Collecting From Web of "Пытается реплицировать выравнивание столбцов GridLayout с помощью ConstraintLayout"

Google ввел идею «барьеров» в последней версии ConstraintLayout которая помогает ответить на этот вопрос на 100%, разрешимом в XML. См. Примечания к выпуску версии ConstraintLayout 1.1.0 beta 1 . Хотя в этой заметке не содержится много информации о новых возможностях, в I / O 2017 говорилось о том, что касается новых вещей.

Новое решение – реплицировать сетку GridLayout на барьеры. Существует вертикальный барьер, расположенный справа от левой TextView и барьер под верхними тремя рядами. Препятствия сдвигаются в зависимости от того, сколько текста присутствует в каждом 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 используя подвижную вертикальную направляющую.

Постройте 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> 

Что-то вроде этого. Введите описание изображения здесь

Я не думаю, что в это время можно выполнить чисто с одним контейнером ConstraintLayout . Надеюсь, что в будущем Google добавит что-то вроде group_id или какой-либо другой способ расчета макета с помощью «align to group».

В то же время, я предлагаю вам использовать контейнеры ConstraintLayout внутри ConstraintLayout . Вот как я это сделал:

Введите описание изображения здесь Введите описание изображения здесь

Чтобы сделать ряды «сеткой» похожими, я использовал « ConstraintLayout Chains ». Количество строк в каждой цепочке ConstraintLayout должно быть одинаковым, поэтому автораспределение будет правильно выравнивать строки. (Хотя они могут оставаться пустыми или скрытыми, если не используются).

Xml gist