[Android] ConstraintLayout 가상 오브젝트 - Guideline, Barrier, Group
Android

[Android] ConstraintLayout 가상 오브젝트 - Guideline, Barrier, Group

728x90

 

 

 ConstraintLayout에는 레이아웃을 구성하기 위한 가상 오브젝트들이 존재한다. 가상 오브젝트란 실제 레이아웃에는 나타나지 않으며, 실제 레이아웃을 배치할 때 좀 더 편리하게 구성할 수 있게 도움을 준다.

 

 

1. Guideline

 가이드라인은 가로 또는 세로의 축을 가진 가상의 뷰로써, 부모 뷰의 특정 위치를 기준점으로 삼을 때 사용한다. 가로/세로를 적용할 때는 LinearLayout과 같이 android:orientation 옵션으로 설정할 수 있다.

 가로/세로를 정했다면 이제 위치를 정해야 한다. 위치를 정하는 옵션으로는 3가지가 있다.

  • app:layout_constraintGuide_begin
  • app:layout_constraintGuide_end
  • app:layout_constraintGuide_percent

 app:layout_constraintGuide_beginapp:layout_constraintGuide_end는 dp와 px과 같이 수치를 적용하는 옵션이고, app:layout_constraintGuide_percent는 퍼센트를 적용하는 옵션이다.

 begin은 왼쪽 혹은 위에서 얼마나 떨어져 있는지를 뜻하고, end는 오른쪽 혹은 아래에서 얼마나 떨어져 있는지를 뜻한다. 예를 들어, 세로축으로 해서 begin은 100dp만큼 설정하면 아래와 같이 된다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="100dp"/>
    
    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_end="100dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 percent는 왼쪽 혹은 위에서 어느 정도의 비율만큼 떨어져 있는지를 뜻하며, 값은 0.0부터 1.0까지 설정할 수 있다. 예를 들어, 왼쪽에서부터 30%의 지점에 가이드라인을 설정하고 싶다면 아래와 같이 하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

2. Barrier

 배리어는 다국어를 고려해서 레이아웃을 짜야할 때 특히 유용하다. 예를 들어, 세로로 배치된 두 개의 텍스트뷰가 있고, 두 텍스트뷰의 오른쪽에 이미지 뷰를 넣으려고 한다. 상황에 따라 두 텍스트뷰의 길이가 달라질 수 있다면, 이미지 뷰는 어떤 텍스트뷰를 기준으로 삼아야 할까?

 이런 상황에서 도움을 주는 것이 배리어다. 배리어는 여러 뷰를 참조하고 지정된 측에서 가장 극단적인 위젯을 기반으로 가이드라인을 만든다.

 배리어에서 주로 사용하는 옵션은 app:constraint_referenced_idsapp:barrierDirection이다. app:constraint_referenced_ids 옵션으로 어떤 뷰를 참조할지를 설정하고, app:barrierDirection 옵션으로 배리어가 참조하는 뷰의 어느 방향에 위치할지를 설정한다.

 위의 예시를 코드로 작성하면 아래와 같게 된다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="50dp">

    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ABC"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ABCDEFGHIJKLMNOP"
        app:layout_constraintTop_toBottomOf="@id/tv_1"
        app:layout_constraintStart_toStartOf="parent"/>

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="tv_1, tv_2"
        app:barrierDirection="end"/>
    
    <ImageView
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:background="@color/black"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="@id/barrier"/>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

3. Group

 여러 개의 뷰들을 동시에 visible, gone 처리해주려면 어떻게 해야 될까? 하나의 ViewGroup으로 묶어서 해당 ViewGroup의 visibility 속성을 변경하거나, 아래와 같이 함수를 하나 만들어서 모든 뷰의 visibility를 변경할 수 있다.

fun setVisibility(isVisible: Boolean) {
    val state = if (isVisible) View.VISIBLE else View.GONE
    
    view1.visibility = state
    view2.visibility = state
    ...
}

 만약 관리해줄 뷰가 많아진다면 코드가 길어지고, ViewGroup으로 묶으면 불필요하게 View 계층이 생긴다는 문제가 있다.

 

 Group을 사용하여 여러 개의 뷰들을 그룹화시키면 한 번의 visible 처리로 그룹 안의 모든 뷰들을 동시에 처리해줄 수 있다. 또한 해당 객체는 ConstraintLayout에 계층 구조로 잡히지 않으며 렌더링 되지 않는다.

 사용법은 간단하다. app:constraint_referenced_ids 옵션으로 관리해줄 뷰의 id를 추가해준 뒤, group의 visibility를 변경해주면 된다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <androidx.constraintlayout.widget.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="tv_1, tv_2"/>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

참고

developer.android.com/reference/androidx/constraintlayout/widget/Barrier

developer.android.com/reference/androidx/constraintlayout/widget/Guideline

developer.android.com/reference/androidx/constraintlayout/widget/Group

 

728x90