ConstraintLayout을 사용하면 플랫 뷰 계층 구조(중첩 뷰 그룹이 없음)로 크고 복잡한 레이아웃을 만들 수 있습니다.

 

 ConstraintLayout에서 뷰의 위치를 정의하려면 보기의 가로 및 세로 제약조건을 각각 하나 이상 추가해야 합니다. 

각 제약조건은 다른 뷰, 상위 레이아웃 또는 보이지 않는 안내선을 기준으로 한 정렬 또는 연결을 나타냅니다. 

각 제약조건은 세로 또는 가로 축을 따라 뷰의 위치를 정의하므로, 각 뷰에는 축마다 하나 이상의 제약조건이 있어야 합니다.

 

뷰를 Layout Editor에 놓으면 제약조건이 없어도 둔 위치에 그래돌 남습니다. 이는 단지 더 쉽게 편집하도록 한 것이며, 기기에서 레이아웃을 실행할 때 뷰에 제약조건이 없으면 [0,0](맨 위 왼쪽 모서리) 위치에 그립니다.

 

제약조건이 누락되어도 컴파일 오류가 발생하지는 않지만, Layout Editor에서는 누락된 제약조건을 툴바에 오류로 표시합니다. 오류 및 기타 경고를 보려면 Show Warnings and Errors를 클릭하세요. 제약조건이 누락되지 않도록 Layout Editor에서는 자동 연결 및 제약조건 추론 기능을 사용하여 제약조건을 자동으로 추가합니다.

 

ConstraintLayout을 프로젝트에 추가 

프로젝트에서 ConstraintLayout을 사용하려면 다음을 진행합니다.

1. 모듈 수준 build.gradle 파일에 선언된 maven.google.com 저장소가 있는지 확인합니다.

    repositories {
        google
()
   
}

2. 다음 예와 같이 동일한 build.gradle 파일에 종속 항목으로 라이브러리를 추가합니다. 최신버전은 다음 예에 표시된 버전과 다를 수 있습니다.

  dependencies {
    implementation
"androidx.constraintlayout:constraintlayout:2.0.0"
}

3. 툴바 또는 동기화 알림에서 Sync Project with Gradle Files를 클릭합니다.

 

 제약조건 추가 또는 삭제

상위 요소 포지셔닝

그림7. 상위 요소의 가로제약조건

 

뷰의측면을 레이아웃의 대응하는 가장자리로 제한합니다.

 

그림에서 뷰의 왼쪽은 상위 레이아웃의 왼쪽 가장자리에 연결되어 있습니다. 여백을 사용하여 가장자리로부터의 거리를 정의할 수 있습니다.

 

 

 

위치 순서 지정

 

 가로 또는 세로로 두 뷰가 표시되는 순서를 정의합니다.

 

그림에서 B는 항상 A의 오른쪽에 있도록 제한되고 C는 A 아래 있도록 제한됩니다. 그러나 이 제약조건은 정렬을 의미하지 않으므로, B는 여전히 위 아래로 이동할 수 있습니다.

 

 

  

정렬

 

뷰의 가장자리를 다른 뷰의 가장자리에 맞게 정렬합니다.

 

위의 그림에서 B의 왼쪽은 A의 왼쪽에 맞게 정렬됩니다.

뷰의 중심으로 정렬하려면 양쪽에 제약조건을 만듭니다.

 

 

 

 

 

제약조건에서 안쪽으로 보기를 드래그하여 기준에서 벗어나 정렬할 수 있습니다.   

예를 들어 아래 그림에서는 24dp 벗어나 정렬된 B를 보여줍니다.

이와 같은 오프셋은 제한된 뷰의 여백으로 정의됩니다. 

 

정렬할 뷰를 모두 선택하나 후 툴바에서 Align을 클릭하여 정렬 유형을 선택할 수도 있습니다.

 

 

기준선 정렬 

  

뷰의 텍스트 기준선을 다른 뷰의 텍스트 기준선에 맞춥니다.

 

그림에서 B의 첫 번째 줄은 A의 텍스트에 맞게 정렬됩니다.

 

기준선 제약조건을 만들려면 제한할 텍스트 뷰를 마우스 오른쪽 버튼으로 클릭한 다음 Show Baseline을 클릭합니다. 그런다음 텍스트 기준선을 클릭하고 선을 다른 기준선으로 드래그 합니다. 

  

안내선으로 제한 

 

뷰를 제한할 수 있는 세로 또는 가로 안내선을 추가할 수 있습니다. 안내선은 앱 사용자에게 표시되지 않습니다. 레이아웃의 가장자리를 기준으로 dp 단위 또는 백분율을 기반으로 레이아웃에 안내선을 배치할 수 있습니다. 

  

안내선을 만들려면 툴바에서 Guidelines를 클릭한 다음 Add Vertical Gduieline 또는 Add Horizontal Guideline을 클릭합니다.

 

점선을 드래그하여 위치를 변경하고 안내선 가장자리의 원을 클릭하여 측정 모드를 전환합니다.

 

경계선으로 제한 

  

안내선과 비슷하게 경계선은 뷰를 제한하는 데 사용할 수 있는 표시되지 않는 선입니다. 단, 경계선은 자체 위치를 정의하지 않으며, 경계선 내로 제한된 뷰 위치를 기반으로 경계선 위치가 이동됩니다. 뷰를 특정한 하나의 뷰가 아니라 뷰 집합으로 제한하려고 할 때 유용합니다.

 

예를 들어 그림에서는 C가 경계선의 오른쪽으로 제한된다는 것을 보여줍니다. 경계는 A와 B의 끝으로 설정됩니다. 따라서 A 또는 B의 오른쪽 중 맨 오른쪽에 있는 것에 따라 경계선이 이동합니다. 

 

경계선을 만들려면 다음 단계를 따르세요.

 1. 툴바에서 Guidelines를 클릭한 후 Add VerticalBarrier 또는 Add Horizontal Barrier를 클릭합니다.

 

 2. Component Tree 창에서 경계선 내의 원하는 뷰를 선택하여 경계선 구성요소로 드래그합니다.

 

 3. Component Tree에서 경계선을 선택하고 Attributes 창을 연 후 barrierDirection을 설정합니다.

 

이제 다른 뷰에서 경계선으로의 제약조건을 만들 수 있습니다. 

 

제약조건 편향 조정 

뷰의 양쪽에 제약 조건을 추가하면 두 제약 조건 사이의 중심에 뷰가 위치하며 기본적으로 편향은 50%입니다. 

 

뷰 크기 조정 

그림 14. 보기를 선택할 때 Attributes 창에는 1 크기 비율, 2 제약조건 삭제, 3 높이/너비 모드, 4 여백 및 5 제약조건 편향을 제어하는 기능이 포함되어 있습니다. 6 제약조건 목록에서 제약조건을 클릭하여 Layout Editor에서 개별 제약조건을 강조 표시할 수도 있습니다.

 

 그림 14에서 번호 3으로 표시된 기호를 클릭하여 높이와 너비를 계산하는 방법을 변경할 수 있습니다.

 

  • 고정 : 아래 텍스트 상자에서 특정 측정기준을 지정하거나 편집기에서 뷰의 크기를 조정합니다.

 

 

  • 콘텐츠 래핑 : 뷰가 콘텐츠에 맞게 필요한 만큼만 확장됩니다.

 

 

  • 제약조건과 일치 : 뷰가 양쪽의 제약조건에 맞게 최대한 많이 확장됩니다(뷰의 여백을 처리한 후).
    그러나 다음 속성과 값을 사용하여 동작을 수정할 수 있습니다.

  • layout_constraintWidth_default

    • 넓히기 : 양쪽의 제약조건에 맞게 뷰를 최대한 확장합니다. 이것이 기본 동작입니다.

    • 래핑 : 콘텐츠에 맞게 필요한 만큼만 뷰를 확장하지만, 제약조건에 필요하면 여전히 뷰를 그보다 작게 만들 수 있습니다. 따라서 이 모드를 사용하는 것과 콘텐츠 래핑을 사용하는 것의 차이점은 너비를 콘텐츠 래핑으로 설정하면 너비가 항상 콘텐츠 너비와 정확히 일치하는 반면, layout_constraintWidth_default를 래핑으로 설정한 상태에서 제약조건과 일치를 사용하면 뷰가 콘텐츠 너비보다 작아질 수 있습니다.

  • layout_contraintWidth_min

    뷰의 최소 너비에 dp 측정기준을 사용합니다.

  • layout_constraintWidth_max

    뷰의 최대 너비에 dp 측정기준을 사용합니다.

키 프레임 애니메이션

 ConstraintLayout에서 ConstraintSet 및 TransitionManager를 사용하여 요소의 크기와 위치 변경사항을 애니메이션으로 보여줄 수 있습니다.

★ 참고 : TransitionManager는 Android 4.0 (API 레벨 14) 이상용 지원 라이브러리에서 사용할 수 있습니다.

ConstraintSet 는 ConstraintLayout 에 있는 모든 하위 요소의 제약조건, 여백 및 패딩을 나타내는 경량 개체입니다.

ConstraintSet 를 보고있는 ConstraintLayout에 적용하면 레이아웃에서 모든 하위 요소의 제약조건을 업데이트합니다.

 

ConstraintSet 를 사용하여 애니메이션을 빌드하려면 애니메이션의 시작 및 종료 키프레임 역할을 할 두 개의 레이아웃 파일을 지정합니다. 그런다음 두 번째 키프레임 파일에서 ConstraintSet 를 로드하고 보고있는 ConstraintLayout에 적용할 수 있습니다.

 ★ 중요 : ConstraintSet 애니메이션은 하위 요소의 크기와 위치만 애니메이션으로 보여줍니다.
색상과 같은 다른 속성은 애니메이션으로 보여주지 않습니다

간단한 코드 예에서는 단일 버튼을 맨 아래로 이동하는 애니메이션을 만드는 방법을 보여줍니다.

 

layout/keyframe_one.xml

<?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"
    android:id="@+id/constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:backgroundTint="@android:color/holo_blue_bright"
        android:onClick="animateToKeyframeTwo"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

layout/keyframe_tow.xml

<?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"
    android:id="@+id/constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:backgroundTint="@android:color/holo_blue_bright"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 MainActivity.kt

class MainActivity : AppCompatActivity() {

    lateinit var constraintLayout: ConstraintLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.keyframe_one)
        constraintLayout = findViewById(R.id.constraint_layout)
    }

    fun animateToKeyframeTwo(view:View) {
        val constraintSet = ConstraintSet()
        constraintSet.load(this, R.layout.keyframe_two)
        TransitionManager.beginDelayedTransition(constraintLayout)
        constraintSet.applyTo(constraintLayout)
    }
}

실행화면

Reference

ConstraintLayout : developer.android.com/training/constraint-layout?hl=ko

 

'Android > Android Developer' 카테고리의 다른 글

MotionLayout  (0) 2020.12.02
Layout 레이아웃  (0) 2020.12.01

+ Recent posts