ConstraintLayout GONE представление занимает пространство
У меня есть ViewHolder
с заголовком сверху, и этот заголовок становится видимым в конкретном случае. В большинстве других случаев заголовок устанавливается как GONE
, Проблема в том, что когда заголовок установлен как GONE, его высота все еще вычисляется, а другие виды spread
по-другому (с большим количеством места между).
Blueprint объяснение:
- Заголовок ограничен
top
,left
а такжеright
, - Два вида ниже находятся в
packed chain
, ограниченный заголовком наtop
,ImageView
кright
и родитель кleft
а такжеbottom
,
А вот скриншот из инспектора макета с выделенным заголовком, который установлен как GONE
:
Согласно документации, вид заголовка при установке на GONE
должен быть сокращен до точки с ограничениями из других представлений, все еще примененных к нему, но заголовок не должен занимать пространство макета и влиять на высоту ConstraintLayout
как установлено wrap_content
,
На этом скриншоте инспектора не ясно, что произошло на самом деле. Заголовок не виден, вид снизу явно ограничен родительской вершиной, но заголовок все еще отображается в инспекторе как полная ширина с указанной высотой.
Я не уверен, если это ошибка, или я должен заставить ConstraintLayout
переоценить себя.
ОБНОВЛЕНИЕ 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:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/list_item_step_conversion_tv_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/gray_very_light"
android:padding="@dimen/activity_vertical_margin"
android:text="@string/favorites"
android:textColor="@android:color/black"
android:textSize="@dimen/default_text_size"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/list_item_step_conversion_tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/gray_dark"
android:textSize="@dimen/medium_text_size"
app:layout_constraintBottom_toTopOf="@+id/list_item_step_conversion_tv_description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/list_item_step_conversion_iv_favorite"
app:layout_constraintTop_toBottomOf="@+id/list_item_step_conversion_tv_header"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Bicycling - light (10-11.9 mph)"/>
<TextView
android:id="@+id/list_item_step_conversion_tv_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="16dp"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/black"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="@+id/list_item_step_conversion_tv_title"
app:layout_constraintRight_toLeftOf="@+id/list_item_step_conversion_iv_favorite"
app:layout_constraintTop_toBottomOf="@+id/list_item_step_conversion_tv_title"
tools:text="182 steps/minute"/>
<ImageView
android:id="@+id/list_item_step_conversion_iv_favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginRight="24dp"
android:layout_marginTop="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/list_item_step_conversion_tv_header"
app:srcCompat="@drawable/ic_not_liked"/>
</android.support.constraint.ConstraintLayout>
ОБНОВЛЕНИЕ 2
После дополнительных наблюдений эта проблема возникает только после звонка notifyDataSetChanged
в RecyclerView.Adapter
, Вот скриншот состояния макета до и после нажатия на favorite
значок одного из предметов.
Объяснение скриншотов:
- С левой стороны,
ViewHolder
с видимымheader
вид включенposition: 2
, Элементы выше отображаются правильно. - После нажмите на
favorite
значок (элемент со значением 242),ViewHolder
наposition: 1
это тот, с видимымheader
вид, в то время какViewHolder
наposition: 2
иметьheader
вид установлен какGONE
, Я ожидалViewHolder
высота уменьшается и имеет такую же высоту, какViewHolder
наposition: 0
,
Имея в виду, что это ViewHolder
имел header
установлен в VISIBLE
в предыдущем состоянии, это может быть что-то с утилизацией, не уверен.
2 ответа
Я решил эту проблему, позвонив view.requestLayout()
* в конце моего адаптера #getView
после обычного звонка binding.executePendingBindings()
,
* Я использую старую школу Adapter
прямо сейчас, так что вы должны искать RecyclerView.Adapter
эквивалентно, наверное #onBindViewHolder()
Кажется, что макет на самом деле правильный - не обращайте внимания на рамку пропавшего объекта в инспекторе, когда виджет помечается как пропавший, мы не выкладываем его снова, так как он будет просто пропущен (в Studio мы делаем, чтобы предоставить более простой способ увидеть, что происходит, но нет смысла делать это на реальном устройстве).
Какую версию ConstraintLayout вы используете? Я, кажется, получаю правильное поведение здесь:
После маркировки первый элемент исчез:
Что сработало для меня, так это установка начальной видимости объекта на "утерянный" и изменение его видимости с помощью кода.
Некоторым это нравится:
Мой xml:
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvMyobject"
style="@style/myStyle"
tools:text="@string/dummy_text"
android:textAlignment="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/anyotherobject"
android:visibility="gone"
/>
Моя деятельность:
if (isSomethingToShow) {
tvMyobject.setVisibility(View.VISIBLE);
tvMyobject.setText(R.string.my_string_to_show);
}