Margin behavior in ConstraintLayout

Viewed 5619

I am having trouble understanding the behavior of margins (android:layout_margin*) when used in ConstraintLayout. Margins seem to only take effect in certain situations, and I am hoping someone can explain it to me (or confirm that it's a ConstraintLayout bug).

I have the following layout...

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
         android:id="@+id/leftView"
         android:layout_width="0dp"
         android:layout_height="100dp"
         android:layout_marginEnd="20dp"
         android:background="@android:color/holo_blue_dark"
         app:layout_constraintEnd_toStartOf="@+id/rightView"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"/>

     <View
         android:id="@+id/rightView"
         android:layout_width="100dp"
         android:layout_height="100dp"
         android:background="@android:color/holo_green_light"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

... which produces the following output...

Expected Output

However, when I change the margin from the leftView to the rightView...

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/leftView"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_blue_dark"
        app:layout_constraintEnd_toStartOf="@+id/rightView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <View
        android:id="@+id/rightView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginStart="20dp"
        android:background="@android:color/holo_green_light"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout> 

... the margin unexpectedly disappears...

Unexpected Output

Can someone explain whether this is expected behavior and, if so, why that is?

3 Answers

Because leftview is depend on rightview, so you can set margin of leftview to rightview.

When a view have margin, it means the view is giving space TO WHICH VIEW IS DEPENDING ON.

if you write android:layout_marginStart="20dp" in rightview, it will not give space to leftview because rightview is not DEPENDING to leftview.

Because the rightView depends on its parent(ConstraintLayout), you set up:

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

The parent is ConstraintLayout. You did that you made the rightView was on the top-right of its parent(ConstraintLayout)

So you used android:layout_marginStart="20dp" in the rightView. The rightView will margin left 20dp with its parent(ConstraintLayout). So there is no white space in this case.


The second case is different with the first case. Looks at the leftView:

The leftView is always on the left side of the rightView because you used app:layout_constraintEnd_toStartOf="@+id/rightView" in the leftView

AND the leftView also depends on its parent(ConstraintLayout) because you used bellow code in the leftView

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

AND you used android:layout_marginEnd="20dp" in the leftView that's mean the leftView will margin right 20dp with the rightView. So there is white space in this case.


You can try to use app:layout_constraintEnd_toEndOf="parent" for the leftView you will see a different.

To get the result you are looking for, you need to build a chain. A chain is correctly defined if all links between the components of the chain are defined.

In your code, rightView must be connected to leftView. Add the following constraint to rightView

app:layout_constraintLeft_toRightOf="@+id/leftView"

and change the existing layout_constraintEnd_toStartOf constraint in leftView to

app:layout_constraintRight_toLefttOf="@+id/rightView"
Related