마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

이 경우 마진이 적용 되지 않는 이유는 무엇일까요?

0 추천

TEST 뷰의 바텀에 마진을 주려고 했는데, 적용이 안되라구요.

그런데 TEST2에서 Top 마진을 주면 적용이 되었습니다.

 

TEST 뷰에 바텀 마진을 주었을 경우

<androidx.constraintlayout.widget.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">

    <TextView
        android:id="@+id/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TEST"
        android:textSize="24sp"
        android:background="@color/light_blue_400"
        android:layout_marginTop="50dp"
        android:layout_marginLeft="10dp"
        android:layout_marginBottom="30dp"
        app:layout_constraintBottom_toTopOf="@id/test2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/test2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/gray_400"
        android:text="TEST2"
        android:textSize="24sp"
        android:layout_marginLeft="10dp"
        app:layout_constraintTop_toBottomOf="@id/test"
        app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

TEST2에 탑마진을 주었을 경우

<androidx.constraintlayout.widget.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">

    <TextView
        android:id="@+id/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TEST"
        android:textSize="24sp"
        android:background="@color/light_blue_400"
        android:layout_marginTop="50dp"
        android:layout_marginLeft="10dp"
        app:layout_constraintBottom_toTopOf="@id/test2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/test2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/gray_400"
        android:text="TEST2"
        android:textSize="24sp"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="10dp"
        app:layout_constraintTop_toBottomOf="@id/test"
        app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

어떤 이유때문일까요?

codeslave (3,940 포인트) 님이 2022년 6월 24일 질문

1개의 답변

0 추천

ConstraintLayout은 Constraints(제약?)을 사용하는 레이아웃입니다. 즉 constraints를 설정하게 되면 margin보다 우선순위가 됩니다.

따라서 첫번째 커스텀뷰는  두번째 뷰에 아래와 같이 constraints가 걸려있으므로 이게 먼저 적용이 됩니다.

<TextView
        android:id="@+id/test2"
..
        app:layout_constraintTop_toBottomOf="@id/test" <!-- 요기에 주목
        app:layout_constraintLeft_toLeftOf="parent" />

이렇게 되면  bottomMargin을 적용한다고 해도 특별한 경우가 아니라면 제대로 설정이 되지 않게 됩니다. 종위에 해당 레이아웃을 그려보시면 쉽게 이해가 가실겁니다. test1 그리고 그 바로 아래에 test2를 그려놓으면 bottomMargin을 적용이 제대로 되지 않습니다.

두번째 경우는 정확히 반대로 하신거구요.

spark (226,420 포인트) 님이 2022년 6월 24일 답변
spark님이 2022년 6월 24일 수정
어음...선생님 그런데 결국에 두번째 경우에도 test2는 test에 constraintBottom_toTopOf="@id/test2" 라는 constraint가 걸려있으므로 두번쨰 경우의 Top margin이 적용되기전에 이 constraint가 먼저 적용되므로 Topmargin이 적용 되지 않아야하는거 아닌가요? 처음에 말씀드렸다시피 두번째 경우에는 Top 마진이 적용되는데..

제가 어디 잘 이해를 못하고있는데 점점 헷갈리네요
제가 레이아웃을 좀 잘못봤네요.

약간의 리서치를 해본 결과,
ConstraintLayout의 top/bottom margin 이 둘다 동작하려면 같은 방향의 constraint가 바로 인접한 뷰에도 적용이 되어야 적용이 됩니다. topMargin 은 top, bottomMargin은 bottom constraint가 인접한 뷰에도 모두 필요합니다.

즉, 첫번째 레이아웃의 경우 test뷰의 bottomMargin이 동작을 하려면 bottom과 관련된 constraint가 둘다 설정이 되어야 합니다.

<TextView
        android:id="@+id/test"
       ...
        app:layout_constraintBottom_toTopOf="@id/test2" />

test2 뷰에도 같은 방향의 constraint인 layout_constraintBottom_toXXX가 적용이 되어야 합니다.
<TextView
        android:id="@+id/test2"
        ...
        app:layout_constraintBottom_toTopOf="@id/test" />

두번째 레이아웃의 경우는 top 관련 constraint가 둘다 설정이 되었으므로 이상없이 동작을 합니다. 만약, 두번째 레이아웃의 test2 뷰에서
app:layout_constraintBottom_toTopOf="@id/test"
을 제거하면 topMargin이 적용이 되지 않습니다.
아 감사합니다..이해가 됐네요..
ConstraintLayout이 해당방향으로 constraint이 설정되어있어야 margin이 적용된다는 것과 인접한 뷰가 있다면 인접한 뷰에도 constraint이 설정되어있어야 margin이 적용된다는것. 두가지를 알아가네요..
근데 왜 굳이 인접한 뷰까지 적용되어있어야 마진을 적용 가능케 만들었는지는 의문이긴하네요.
감사합니다.
...