Home > Enterprise >  ConstraintLyaout GONE view doesn't affect constraints
ConstraintLyaout GONE view doesn't affect constraints

Time:11-18

I've this layout:

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@ id/myLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@ id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/text2"
        android:text="Left"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"/>
    
    <TextView
        android:id="@ id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:text="Center"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"/>
    
    <TextView
        android:id="@ id/text3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/text2"
        android:text="Right"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"/>
        

</androidx.constraintlayout.widget.ConstraintLayout>

When I change the visibility of the center and left textviews to gone, The right textview still remains on the right side, instead of being pulled to the left side since it's constraints are gone.

Any idea why?

CodePudding user response:

To solve the problem I will recommend you to use LinearLayout and the property weightSum. So it will be something like this:

<LinearLayout
    android:id="@ id/myLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:weightSum="3">

    <TextView
        android:id="@ id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Left"
        android:textSize="20sp"
        android:gravity="center"
        android:layout_weight="1"/>

    <TextView
        android:id="@ id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Center"
        android:textSize="20sp"
        android:gravity="center"
        android:layout_weight="1"/>

    <TextView
        android:id="@ id/text3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Right"
        android:textSize="20sp"
        android:gravity="center"
        android:layout_weight="1"/>
</LinearLayout>

CodePudding user response:

You should not expect the right view to be pulled all the way over to the left if you make the left and center views gone. When the views are made gone, they are shrunk to a point (zero width and height), but their constraints remain intact. In their gone state, the right view is constrained to the center view which is still at the center of the layout. See Visibility Behavior. The diagram at this link is a little misleading since it may appear (it did to me, initially) that view "B" assumes the left constraint of view "A". That is not the case: All the constraints remain as they were before gone is applied.

That is the "why" and the answer to your question. There are probably several ways to fix it. One way that leaves your current layout intact is to change the horizontal bias of the center view to zero which will move it all the way to the left when the views are made gone. You will also make the right view's bias zero to move it all the way to the left, too. You will need to reset the biases to 50% if you make the views visible again.

CodePudding user response:

I fixed using a barrier and app:barrierAllowsGoneWidgets="false" and setting the right view constrained to the barrier

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@ id/myLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@ id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/text2"
        android:text="Left"
        android:visibility="gone"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@ id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:text="Center"
        android:visibility="gone"
        android:textSize="20sp"
        
        app:layout_constraintTop_toTopOf="parent"/>

    <androidx.constraintlayout.widget.Guideline
        android:id="@ id/guideLine"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.5"
        android:orientation="vertical"/>


    <TextView
        android:id="@ id/text3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/barrier"
        android:text="Right"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"/>
    
    <androidx.constraintlayout.widget.Barrier
        android:id="@ id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierAllowsGoneWidgets="false"
        app:constraint_referenced_ids="text1,text2"
        app:barrierDirection="end"/>


</androidx.constraintlayout.widget.ConstraintLayout>
  • Related