ConstraintLayout: повторное выравнивание базового ограничения в случае, если для видимости зависимого вида было установлено значение GONE.

Есть ли способ перенастроить базовое ограничение для TextView в случае, если видимость зависимого представления была установлена ​​​​на GONE?

Мой код макета:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TEST TITLE"
        android:textColor="@color/black"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <TextView
        android:id="@+id/subtitle1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SUBTITLE 1"
        android:textSize="11sp"
        app:layout_constraintBaseline_toBaselineOf="@+id/subtitle2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/subtitleSpace"
        app:layout_constraintRight_toRightOf="parent"/>

    <android.support.v4.widget.Space
        android:id="@+id/subtitleSpace"
        android:layout_width="12dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/subtitle1"
        app:layout_constraintRight_toLeftOf="@+id/subtitle2"/>

    <TextView
        android:id="@+id/subtitle2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:text="SUBTITLE 2"
        android:textSize="14sp"
        app:layout_constraintLeft_toRightOf="@+id/subtitleSpace"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title"/>

</android.support.constraint.ConstraintLayout>

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

Когда я устанавливаю для subtitle2 видимости TextView значение GONE, мой макет будет выглядеть так: введите здесь описание изображения

Поэтому мне интересно, есть ли какое-то ограничение, которое может перестроить базовую линию в случае, если зависимое представление отсутствует.


person novachevskyi    schedule 07.04.2017    source источник


Ответы (2)


Для виджетов GONE можно указать альтернативные поля (см. Поля при подключении к виджет GONE), но я не знаю такой альтернативы для базовых показателей.

Один из способов удовлетворить ваше требование — указать 0dp невидимый TextView, который имеет те же характеристики, что и GONE TextView, размещенный рядом с тем же представлением. subtitle1 и subtitle2 будут привязаны к базовой линии этого нового TextView. Несмотря на то, что новый TextView не отображается на экране и имеет нулевую ширину, он по-прежнему сохраняет базовую линию.

Теперь, когда subtitle2 превратится в GONE, subtitle1 переместится в центр, но сохранит свое вертикальное положение. (Указание 0dp и invisible с нулевым текстом является излишним, но дает понять, что виджет не должен отображаться.)

Вот XML с этими изменениями:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TEST TITLE"
        android:textColor="#FF000000"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <TextView
        android:id="@+id/subtitle1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SUBTITLE 1"
        android:textSize="11sp"
        app:layout_constraintBaseline_toBaselineOf="@+id/viewForBaseline"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/subtitleSpace"
        app:layout_constraintRight_toRightOf="parent" />

    <android.support.v4.widget.Space
        android:id="@+id/subtitleSpace"
        android:layout_width="12dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/subtitle1"
        app:layout_constraintRight_toLeftOf="@+id/subtitle2" />

    <TextView
        android:id="@+id/subtitle2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:text="SUBTITLE 2"
        android:textSize="14sp"
        android:visibility="gone"
        app:layout_constraintBaseline_toBaselineOf="@+id/viewForBaseline"
        app:layout_constraintLeft_toRightOf="@+id/subtitleSpace"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title" />

    <TextView
        android:id="@+id/viewForBaseline"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="14sp"
        android:visibility="invisible"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title" />

</android.support.constraint.ConstraintLayout> 
person Cheticamp    schedule 10.04.2017
comment
Спасибо за ваше предложение! Я уже применил то же решение, что и вы, но мне все же было интересно, есть ли какие-то ограничения для базовых линий текстового представления GONE. Я действительно не хочу оставлять пустые виды в своем макете, чтобы избежать осложнений и сделать его чище. - person novachevskyi; 10.04.2017
comment
Я думаю, что ответ на этот вопрос заключается в том, что нет, но имело бы смысл иметь такую ​​вещь. - person Cheticamp; 10.04.2017

Вы можете сделать это программно, вне кода xml. Это не идеальное решение, но вы получите точный набор ограничений, которые хотите. Базовая идея:

private val defaultConstrainSet = ConstraintSet()
private val newConstrainSet = ConstraintSet()

init {
    defaultConstrainSet.clone(constraintLayout)
    newConstrainSet.apply {
        clone(constraintLayout)
        // here put your new constrains, eg. :
        clear(R.id.subtitle1, ConstraintSet.BASELINE)
        connect(R.id.agenda_index, ConstraintSet.TOP, R.id.title, ConstraintSet.BOTTOM)
    }
}

а потом

    if (/* subtitle2 is visible */) {
        defaultConstrainSet.applyTo(constraintLayout)
    } else {
        newConstrainSet.applyTo(constraintLayout)
    }
person Hammer    schedule 17.02.2021