Взвешенные цепочки ConstraintLayout программно

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

Я попытался установить ширину просмотров на MATCH_CONSTRAINT, но потом они исчезли. Также установка горизонтального веса ничего не меняет.

Это работает:

<android.support.constraint.ConstraintLayout
    android:id="@+id/constraintLayoutTop"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    app:layout_constraintBottom_toTopOf="@+id/constraintLayoutBottom"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="1"
        app:layout_constraintBottom_toTopOf="@+id/textView3"
        app:layout_constraintEnd_toStartOf="@+id/textView2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="2"
        app:layout_constraintBottom_toTopOf="@+id/textView4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/textView1"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/textView4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView1" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/textView3"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />
</android.support.constraint.ConstraintLayout>

Это не работает:

ConstraintLayout bottomLayout = findViewById(R.id.constraintLayoutBottom);
TextView textView;
ConstraintSet set;

List<List<Integer>> rows = new ArrayList<>();
List<Integer> col1 = new ArrayList<>();
List<Integer> col2 = new ArrayList<>();

col1.add(1);
col1.add(2);
col2.add(3);
col2.add(4);

rows.add(col1);
rows.add(col2);

for (int y = 0; y < rows.size(); y++) {
    List<Integer> cols = rows.get(y);
    for (int x = 0; x < cols.size(); x++) {
        Integer i = cols.get(x);

        textView = new TextView(getApplicationContext());
        textView.setText(i.toString());
        textView.setId(i);

        //ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
        //textView.setLayoutParams(params); // this makes views disappear!

        bottomLayout.addView(textView);

        int leftId = i == 1 || i == 3 ? ConstraintSet.PARENT_ID : i - 1;
        int topId = i == 1 || i == 2 ? ConstraintSet.PARENT_ID : i - 2;
        int rightId = i == 2 || i == 4 ? ConstraintSet.PARENT_ID : i + 1;
        int bottomId = i == 3 || i == 4 ? ConstraintSet.PARENT_ID : i + 2;

        set = new ConstraintSet();
        set.clone(bottomLayout);
        //set.constrainWidth(textView.getId(), ConstraintSet.MATCH_CONSTRAINT); // this makes views disappear!
        set.connect(textView.getId(), ConstraintSet.LEFT, leftId, ConstraintSet.RIGHT, 0);
        set.connect(textView.getId(), ConstraintSet.TOP, topId, ConstraintSet.BOTTOM, 0);
        set.connect(textView.getId(), ConstraintSet.RIGHT, rightId, ConstraintSet.LEFT, 0);
        set.connect(textView.getId(), ConstraintSet.BOTTOM, bottomId, ConstraintSet.TOP, 0);
        set.applyTo(bottomLayout);
    }
}

Как мне добиться того же в java?


comment
Мне нужна таблица 10x10, и я начал с TableLayout и нескольких TableRow с вложенными TextView, но мне не удалось сделать их отзывчивыми. Отлично смотрится на больших телефонах, но не на маленьких или наоборот.   -  person masewo    schedule 29.01.2018
comment
Только что попробовал это прямо сейчас в соответствии с вашим образцом кода. Но тоже не отзывается. Мне нужно добавить layout_width в CardView, и если я выберу spanCount из 10, то это превысит ширину экрана.   -  person masewo    schedule 29.01.2018
comment
Если у меня есть 10 TextView подряд, я хочу, чтобы они заполняли всю ширину экрана, поэтому я хочу макет в процентах, что должен уметь делать ConstraintLayout.   -  person masewo    schedule 29.01.2018
comment
Наконец я выбрал другой подход с RecyclerView и GridLayoutManager. Это примерно в 10 раз быстрее, чем с ConstraintLayout.   -  person masewo    schedule 01.02.2018


Ответы (2)


Я думаю, что здесь есть некоторые проблемы, которые нужно решить.

Например, в коде отсутствует создание цепочек (оба горизонтальный и vertical) и вам нужно применить ConstraintSet() только один раз, после завершения настройки.

Я пытался исправить код, и он работает для меня.

ConstraintLayout bottomLayout = findViewById(R.id.constraintLayoutBottom);
TextView textView;
ConstraintSet set = new ConstraintSet();

List<List<Integer>> rows = new ArrayList<>();
List<Integer> col1 = new ArrayList<>();
List<Integer> col2 = new ArrayList<>();

set.clone(bottomLayout);

col1.add(1);
col1.add(2);
col2.add(3);
col2.add(4);

rows.add(col1);
rows.add(col2);

for (int y = 0; y < rows.size(); y++) {
    List<Integer> cols = rows.get(y);
    for (int x = 0; x < cols.size(); x++) {
        Integer i = cols.get(x);

        textView = new TextView(getApplicationContext());
        textView.setText(i.toString());
        textView.setId(i);

        bottomLayout.addView(textView);

        int leftId = i == 1 || i == 3 ? ConstraintSet.PARENT_ID : i - 1;
        int topId = i == 1 || i == 2 ? ConstraintSet.PARENT_ID : i - 2;
        int rightId = i == 2 || i == 4 ? ConstraintSet.PARENT_ID : i + 1;
        int bottomId = i == 3 || i == 4 ? ConstraintSet.PARENT_ID : i + 2;

        set.connect(textView.getId(), ConstraintSet.LEFT, leftId, ConstraintSet.RIGHT, 0);
        set.connect(textView.getId(), ConstraintSet.TOP, topId, ConstraintSet.BOTTOM, 0);
        set.connect(textView.getId(), ConstraintSet.RIGHT, rightId, ConstraintSet.LEFT, 0);
        set.connect(textView.getId(), ConstraintSet.BOTTOM, bottomId, ConstraintSet.TOP, 0);
    }
}

set.createHorizontalChain(
    ConstraintSet.PARENT_ID,
    ConstraintSet.LEFT,
    ConstraintSet.PARENT_ID,
    ConstraintSet.RIGHT,
    new int[] {1, 2},
    null, // Here you can set a float array with the weights for your views
    ConstraintSet.CHAIN_SPREAD
)

set.createHorizontalChain(
    ConstraintSet.PARENT_ID,
    ConstraintSet.LEFT,
    ConstraintSet.PARENT_ID,
    ConstraintSet.RIGHT,
    new int[] {3, 4},
    null, // Here you can set a float array with the weights for your views
    ConstraintSet.CHAIN_SPREAD
)

set.createVerticalChain(
    ConstraintSet.PARENT_ID,
    ConstraintSet.TOP,
    ConstraintSet.PARENT_ID,
    ConstraintSet.BOTTOM,
    new int[] {1, 3},
    null, // Here you can set a float array with the weights for your views
    ConstraintSet.CHAIN_SPREAD
)

set.createVerticalChain(
    ConstraintSet.PARENT_ID,
    ConstraintSet.TOP,
    ConstraintSet.PARENT_ID,
    ConstraintSet.BOTTOM,
    new int[] {2, 4},
    null, // Here you can set a float array with the weights for your views
    ConstraintSet.CHAIN_SPREAD
)

set.applyTo(bottomLayout);
person Mike Grimm    schedule 30.11.2020

Попробуйте использовать SequenceLayout. Проще и гибче.

person Yashar PourMohammad    schedule 09.04.2019