Странное изменение в поведении ConstraintLayout с 1.1.2 до 1.1.3 - PullRequest
0 голосов
/ 26 ноября 2018

Я заметил странное изменение в поведении ConstraintLayout с 1.1.2 до 1.1.3, которое может вызвать много проблем в макете.Кроме того, я лично считаю, что это ошибка, потому что это поведение должно быть неправильным.

Проверьте следующий макет:

<android.support.constraint.ConstraintLayout 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="match_parent">    
<Button
    android:id="@+id/test1_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="test1"
    app:layout_constraintTop_toTopOf="@id/test2_btn"
    app:layout_constraintBottom_toBottomOf="@id/test2_btn"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/test2_btn"
    app:layout_constraintHorizontal_chainStyle="spread_inside"
    app:layout_constraintHorizontal_bias="1"/>

<Button
    android:id="@+id/test2_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="test2"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/test1_btn"/>
</android.support.constraint.ConstraintLayout>

Вот как этот макет отображается в обеих версиях 1.1.2и 1.1.3 из ConstraintLayout:

enter image description here

Теперь мы добавляем android:visibility="gone" к test1_btnConstraintLayout версии 1.1.2 макет отображается следующим образом:

enter image description here

Это совершенно логично , поскольку мы имеемapp:layout_constraintHorizontal_bias="1" установлено, поэтому test2_btn должно находиться в правой части цепочки.Теперь, если мы используем ConstraintLayout версию 1.1.3, макет будет отображаться следующим образом:

enter image description here

Что случилось?Почему я потерял смещение цепи?

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Я согласен со многими ответами Четикампа, но я хочу высказать некоторые вещи.

Неясно, что должно произойти, когда цепочка является diff_inside, так как этот тип цепочки диктует, что конечные виджетыпридерживаться сторон.

Смещение применяется только в двух ситуациях:

  • Для вида с фиксированным размером, который ограничен с обеих сторон
  • Вкл.головка цепи с упакованной цепью

В случае разветвленной цепи смещение не оказывает влияния;другие ограничения переопределяют его.

Итак, виджет GONE должен по-прежнему участвовать в цепочке - его размеры равны нулю.

Это реальная проблема,Я вижу строку документации, которая гласит: «С точки зрения вычислений макета виджеты GONE все еще являются его частью», поэтому я понимаю, как вы это сделаете.

Однако ,Я думаю, что есть аргумент в другом направлении.Вместо цепочки из двух элементов представьте цепочку из трех.С головкой цепи VISIBLE вы ожидаете увидеть

View1 <--- space ---> View2 <--- space ---> View3

Теперь, когда вы установите головку цепи на GONE, что вы ожидаете?Я думаю, что большинство разработчиков предпочли бы это:

View2 <-------------- space --------------> View3

, чем это:

<----- space ----> View2 <----- space ----> View3

Если вы согласитесь, и вы думаете, что обычно разработчик Android будетскорее, посмотрите, как неподвижные VISIBLE виды распределенной внутренней цепи будут сдвинуты к краям "как обычно", тогда я думаю, что логическим выводом этого аргумента является новое поведение, видимое в v1.1.3.

Я думаю, что документация должна быть обновлена, чтобы прояснить эту ситуацию.Либо GONE представления участвуют в цепочке (просто как невидимая точка), или GONE представления не участвуют в цепочке (за исключением случаев, когда атрибуты заголовка цепочки изменяют цепочку в целом).).

0 голосов
/ 27 ноября 2018

Чтобы получить старое поведение при использовании версии 1.1.3, добавьте этот атрибут в ваш тег <ConstraintLayout>:

app:layout_optimizationLevel="direct|barrier"

В версии 1.1 библиотеки ConstraintLayout введено новые оптимизации ,Эти оптимизации анализируют ваш ConstraintLayout и ищут ограничения, которые можно удалить или упростить.

Начиная с версии 1.1.2, единственными оптимизациями, включенными по умолчанию, были direct и барьер .Версия 1.1.3 также включает цепочка по умолчанию .Вы можете вернуться к поведению 1.1.2, указав вручную, какие оптимизации должны быть включены.


Чтобы показать, что это реальная проблема, я попытался включить цепочкуоптимизации при использовании версии 1.1.2.

Первый снимок экрана сделан с использованием версии 1.1.2 и вашего опубликованного макета (с добавленным атрибутом android:gone).Затем я добавил этот атрибут в корневой тег ConstraintLayout:

app:layout_optimizationLevel="chains"

, и теперь я вижу то же поведение, которое вы обнаружили в версии 1.1.3:

image image

0 голосов
/ 26 ноября 2018

Похоже, вы определили проблему, но не по той причине, по которой вы думаете, ИМХО.Если вы посмотрите на документацию для ConstraintLayout смещения в разделе «Позиционирование», то в ней говорится:

По умолчанию при возникновении таких противоположных ограничений является центрирование виджета;но вы можете настроить расположение в пользу одной стороны над другой, используя атрибуты смещения:

layout_constraintHorizontal_bias будет применяться к виджету, а не к цепочке.Однако это влияет на смещение цепочки, если цепочка представляет собой упакованную цепочку и смещение применяется к виджету в цепочке.Неясно, что должно произойти, когда цепочка spread_inside, поскольку этот тип цепочки диктует, что конечные виджеты придерживаются сторон.

В той же документации говорится:

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

Но с точки зрения вычислений макета,GONE виджеты все еще являются его частью, с важным отличием:

  • Для прохода макета их размерность будет рассматриваться как ноль (в основном, они будут разрешены в точку)
  • Если у них есть ограничения для других виджетов, они все равно будут соблюдаться, но любые поля будут как бы равны нулю

Таким образом, виджет GONE все равно должен участвовать вцепь - она ​​просто имеет нулевые размеры.В вашем примере я бы ожидал, что правое TextView останется неподвижным, когда видимость левого TextView изменится на GONE.Таким образом, поведение 1.1.2 кажется правильным, в то время как 1.1.3 кажется несовместимым с документацией.

...