ConstraintLayout GONE view occupies space
android, android-constraintlayout, constraint-layout-chains
Solution
I've solved this issue by calling `view.requestLayout()`* in the end of my adapter's `#getView`, after the usual call to `binding.executePendingBindings()`.
*I'm using an old-school `Adapter` right now, so you should search for the `RecyclerView.Adapter`'s equivalent, probably `#onBindViewHolder()`
Problem
I have a `ViewHolder` with the header on top and that header becomes visible in a specific case. In most other cases, the header is set as `GONE`. The problem is that when a header is set as GONE, its height is still calculated and other views are `spread` differently (with more space between). Here is a layout blueprint: Blueprint explanation: - The header is constrained to `top`, `left` and `right`. - Two views below are in `packed chain`, constrained to a header on `top`, `ImageView` to the `right` and parent to the `left` and `bottom`. And here is a screenshot from the layout inspector with highlighted header view which is set as `GONE`: According to documentation, the header view, when set to `GONE` should be shrunk to point with constraints from other views still applied to it, but the header should not occupy layout space and affect the height of the `ConstraintLayout` as it is set as `wrap_content`. In this inspector screenshot, it's not clear what happened actually. The header is not visible, a bottom view is obviously constrained to parent top, but the header is still shown in the inspector as full width with specified height. I'm not sure if this is a bug or I should force `ConstraintLayout` to re-measure itself. XML UPDATE: ``` <?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> ``` UPDATE 2 After additional observations, this problem occurs only after a call to `notifyDataSetChanged` in `RecyclerView.Adapter`. Here is a screenshot of layout state before and after the click to the `favorite` icon to one of the items. Screenshots explanation: - On the left side, `ViewHolder` with visible `header` view is on `position: 2`. Items above are displayed correctly. - After click on `favorite` icon (item with value 242), `ViewHolder` on `position: 1` is the one with visible `header` view, while the `ViewHolder` on `position: 2` have `header` view set as `GONE`. I was expecting for `ViewHolder` height to decrease and have the same height as `ViewHolder` on `position: 0`. Having in mind that this `ViewHolder` had `header` set to `VISIBLE` in previous state, it might have something with recycling, not sure.