본문 바로가기

안드로이드/View

[안드로이드] ConstraintLayout - Barrier에 대하여

오늘은 ConstraintLayout에서 Barrier에 대한 속성에 대하여 정리를 해보려고 한다.

 

- Barrier

 

 

배리어는 한국말로 '방어막'이다. 이러한 방어막은 방어막을 쓴 사람을 주위로 일종의 막이 형성되며, 해당 막 바깥과 안쪽 사이의 물리력을 차단해주는 것을 의미한다.

 

https://developer.android.com/reference/androidx/constraintlayout/widget/Barrier - 안드로이드 공식 개발문서, androidx.constraintlayout.widget.Barrier 중 발췌

 

이러한 맥락에서 ConstraintLayout의 배리어의 의미를 주입시켜보자. 일단 Barrier는 자바의 Object를 상속받는 android.view.View를 상속받는다. 그리고 배리어라는 의미로 미루어 보아 무엇인가의 침입을 막는것인데, 사실상 View에서 뭔가의 침입을 막는다는건 다른 View가 영역을 침범하는 것 밖에 없다.

 

그러면 이러한 맥락에서 미루어 보아, Constraintlayout의 배리어가 하는 역할은 아래 2가지 정도가 있지 않을까 하는 예측이 도출된다.

 

  1. 특정 View가 다른 View의 영역을 침범하지 않게 하기 위하여
  2. 특정 View가 일정공간 이상을 차지하지 않게 하기 위하여

실질적으로 사용해서 어떤 역할을 하는지 한번 보겠다. 일단 속성과 어떻게 선언을 해야 하는지 알아보자.

 

먼저 속성이다. 

  • constraint_referenced_ids : 배리어가 참조해야 하는 view의 id를 나열하는 것이다. 쉽게 얘기하면, 이 속성에 쓴 id 값을 가진 view를 보호해야 한다고 선언해주는 부분이다.
    콤마(,) 기준으로 여러개의 id쓸 수 있다.

  • barrierDirection : constraint_referenced_ids에서 보호해줘야 하는 View를 어떤 위치에 대하여 보호해줄지 선언해주는 속성이다.  해당 속성값은 start, end, top, bottom, left, right가 있다.

  • barrierAllowGoneWidgets : 배리어가 참조하고 있는 View의 Visibility가 GONE이 될 시 배리어가 그대로 남아있어도 되니? 하고 묻는 속성이다. true, false로 결정되며, true일 경우 배리어는 그대로 작동되며, false일 시 배리어는 barrierDirection에 준 속성의 parent 위치로 가게 된다.

 

그렇다면 선언하는 방법은 작성한 예시코드에서 확인하자.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="match_parent"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="테스트"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/barrier"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="이 것은 테스트를 위한 배리어 입니다."
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/barrier"
        app:layout_constraintTop_toBottomOf="@id/btn1" />



    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/black"
        app:barrierAllowsGoneWidgets="true"
        app:barrierDirection="start"
        app:constraint_referenced_ids="tv1" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

Barrier 부분을 보면 현재 배리어가 참조하는 View는 TextView이다. 그리고 Direction은 start로 정해주었다. 그리고 barrierAllowsGoneWidgets 값은 true로 설정했다.

 

이것들을 풀어서 설명하면 아래와 같다.

배리어는 tv1이라는 아이디 값을 가진 TextView를 보호해주세요. 근데 그 보호해주는 방향은 TextView의 start 방향이에요. 그리고 만약에 TextView가 사라져도 계속해서 배리어가 그 역할을 유지해주세요.

 

그렇다면 결과를 스크린샷을 통해서 확인해보자.

 

 

위 사진은 위에서 작성한 코드블럭을 그대로 실행했을 때이다. '이 것은 테스트를 위한 배리어 입니다.' 글귀가 배리어에 의하여 짤리고 ... 표시가 된 것을 확인할 수 있다.

 

 

이번엔 중간에 있던 TextView가 없어졌을 때, barrierAllowGoneWidgets 속성이 true일 때의 사진이다. TextView는 사라졌지만, 여전히 배리어는 제대로 작동하는 것을 볼 수 있다. 그런데 이때 약간의 위치가 변경될 수 있다.

 

중간에 'Hello World' TextView의 경우에는 constraint가

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"


이렇게 설정되어있다. 따라서 View가 GONE이 되면, Width가 쪼그라들면서 너비가 줄어들게 된다. 이거에 맞춰서 배리어도 위치가 살짝 조정이 된다.

 

 

이번엔 barrierAllowGoneWidgets 속성이 false 일 때 사진이다. 이 속성이 false 경우 TextView의 Visibility가 GONE이 될 경우 배리어가 더이상 View를 참조하지 않아서 배리어가 있어야할 barrierDirection 속성에 선언된 parent 위치로 가게 된다.

 

그래서 배리어 위치에 따라 Button의 위치도 바뀌기 때문에 버튼이 반만큼 화면에서 보이지 않는 것을 확인할 수 있다.