[Android/안드로이드] ConstraintLayout 에 대하여

2020. 5. 29. 18:17Android/깨알 개념 정리

ConstraintLayout을 사용해야 하는 이유

1. 

  • layout_constraintLeft_toLeftOf
  • layout_constraintLeft_toRightOf

  • layout_constraintRight_toLeftOf

  • layout_constraintRight_toRightOf

  • layout_constraintTop_toTopOf

  • layout_constraintTop_toBottomOf

  • layout_constraintBottom_toTopOf

  • layout_constraintBottom_toBottomOf

  • layout_constraintBaseline_toBaselineOf

  • layout_constraintStart_toEndOf

  • layout_constraintStart_toStartOf

  • layout_constraintEnd_toStartOf

  • layout_constraintEnd_toEndOf

2. 성능이 더 좋다 / 훨씬 빠르다 

Android의 N 릴리스에서 ConstraintLayout 클래스는 RelativeLayout과 유사한 기능을 제공하지만 비용은 훨씬 저렴합니다.

 

 

ConstraintLayout 개발 가이드 

1. Relative positioning (상대적 위치)

 

Relative positioning은 ConstraintLayout에서 레이아웃을 작성하는 기본 빌딩 블록 중 하나입니다. 이러한 제약 조건을 사용하면 지정된 위젯을 다른 위젯에 상대적으로 배치 할 수 있습니다. 가로 및 세로 축에서 위젯을 제한 할 수 있습니다.

  • 가로 축 : 왼쪽, 오른쪽, 시작 및 끝면
  • 세로 축 : 위쪽, 아래쪽 및 텍스트 기준선

 

일반적인 개념은 위젯의 주어진면을 다른 위젯의 다른면으로 제한하는 것입니다.

예를 들어, 버튼 B를 버튼 A의 오른쪽에 배치하려면 (그림 1) :

그림 1-상대 위치 지정 예

 

아래와 같이 해야한다. 

<Button android:id="@+id/buttonA" ... /> 
    <Button android:id="@+id/buttonB" ... 
        app:layout_constraintLeft_toRightOf="@+id/buttonA" />

 

이것은 시스템에게 버튼 B의 왼쪽이 버튼 A의 오른쪽으로 제한되도록한다는 것을 알려줍니다. 이러한 위치 제한은 시스템이 양쪽이 동일한 위치를 공유하도록 시도한다는 것을 의미합니다.

 

그림 2-상대 위치 제약

 

사용 가능한 제약 조건 목록은 다음과 같습니다 (그림 2).

  • layout_constraintLeft_toLeftOf
  • layout_constraintLeft_toRightOf
  • layout_constraintRight_toLeftOf
  • layout_constraintRight_toRightOf
  • layout_constraintTop_toTopOf
  • layout_constraintTop_toBottomOf
  • layout_constraintBottom_toTopOf
  • layout_constraintBottom_toBottomOf
  • layout_constraintBaseline_toBaselineOf
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
  • layout_constraintEnd_toEndOf

 

그들은 모두 id다른 위젯 또는 parent(상위 컨테이너, 즉 ConstraintLayout을 참조 할) 위젯 을 참조합니다.

<Button android:id="@+id/buttonB" ... app:layout_constraintLeft_toLeftOf="parent" />

 

<Button android:id="@+id/buttonB" ... 
    app:layout_constraintLeft_toLeftOf="parent" />

 

2. Margins (여백)

 

그림 3-상대 포지셔닝 마진

 

측면 여백이 설정되면 해당 제약 조건 (있는 경우)에 적용되어 (그림 3) 대상과 소스 측면 사이의 간격으로 여백이 적용됩니다. 일반적인 레이아웃 여백 속성을이 효과에 사용할 수 있습니다.

 

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

 

마진은 양수이거나 0과 같을 수 있으며 너비를 가진다. 

 

GONE 위젯에 연결된 경우 여백

 

위치 구속 조건 대상의 가시성이 View.GONE인 경우 다음 속성을 사용하여 사용할 다른 여백 값을 나타낼 수도 있습니다.

 

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

 

3. Centering positioning and bias (센터링 포지셔닝)

유용한 기능은 ConstraintLayout"불가능한"제약을 다루는 방법입니다. 예를 들어 다음과 같은 것이 있다

 

<androidx.constraintlayout.widget.ConstraintLayout ...> 
    <Button android:id="@+id/button" ... 
    app:layout_constraintLeft_toLeftOf="parent" 
    app:layout_constraintRight_toRightOf="parent/> 
</>

 

ConstraintLayout와 크기가 정확히 일치 하지 않으면 Button두 제약 조건을 동시에 만족시킬 수 없습니다 (양쪽이 원하는 위치에있을 수 없음).

 

그림 4-중심 위치

 

이 경우에 발생하는 것은 구속 조건이 위젯을 똑같이 잡아 당기는 반대 힘처럼 작용한다는 것입니다 (그림 4). 위젯이 부모 컨테이너의 중앙에 위치하도록합니다. 이것은 수직 구속 조건에도 유사하게 적용됩니다.

 

bias

 

이러한 반대 제약 조건이 발생하면 기본값은 위젯을 중앙에 배치하는 것입니다. 그러나 바이어스 속성을 사용하여 한 쪽을 다른 쪽보다 선호하도록 위치를 조정할 수 있습니다.

 

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

 

그림 5-bias를 이용한 센터링 포지셔닝

 

예를 들어, 다음은 기본 50 % 대신 30 % 바이어스로 왼쪽을 만들어 왼쪽이 짧아 지도록 위젯을 왼쪽으로 더 기울입니다 (그림 5).

 

<androidx.constraintlayout.widget.ConstraintLayout ...> 
    <Button android:id="@+id/button" ... 
    app:layout_constraintHorizontal_bias="0.3" 
    app:layout_constraintLeft_toLeftOf="parent" 
    app:layout_constraintRight_toRightOf="parent/> 
</>

 

bias를 사용하면 화면 크기 변경에 더 잘 적응할 수있는 사용자 인터페이스를 만들 수 있습니다.

 

4. 1.1버전에서 Circular positioning  (원형 위치)

 

각도와 거리에서 다른 위젯 중심을 기준으로 위젯 중심을 구속 할 수 있습니다. 이를 통해 위젯을 원에 배치 할 수 있습니다 (그림 6 참조). 다음과 같은 속성을 사용할 수 있습니다.

 

  • layout_constraintCircle : 기준으로 참조할 view의 id
  • layout_constraintCircleRadius : 참조한 view와의 거리(반지름)
  • layout_constraintCircleAngle : 0부터 360까지 참조한 뷰로부터의 각도 

그림 6-원형 위치

 

그림 6-원형 위치



<Button android:id="@+id/buttonA" ... />

<Button android:id="@+id/buttonB" ... 
app:layout_constraintCircle="@+id/buttonA" 
app:layout_constraintCircleRadius="100dp" 
app:layout_constraintCircleAngle="45" />

 

5. Visibility behavior (가시성 행동)

 

이 특성은 View.GONE 속성과 관련 된 내용 입니다.

일반적인 GONE 특성 처럼, 특정 위젯을 GONE 으로 처리 하게 되면 위젯이 표시 되지 않고 레이아웃에 포함 되지 않습니다.

GONE 으로 처리 된 위젯은 기본적으로 width, height 이 0 으로 간주되며, 그 위젯에 정의 된 margin 또한 0 으로 처리 됩니다.

 

  • 레이아웃 패스의 경우 치수가 0으로 간주됩니다 (기본적으로 포인트로 해석 됨).
  • 다른 위젯에 제약이있는 경우 여전히 존중되지만 여백은 0과 같습니다.

그림 7-가시성 동작

 

이 특정 동작을 통해 레이아웃 GONE을 중단하지 않고 위젯을 임시로 표시 할 수있는 레이아웃을 만들 수 있습니다 (그림 7).

이는 간단한 레이아웃 애니메이션을 수행 할 때 특히 유용합니다.

 

참고 : 사용 된 여백은 B가 A에 연결할 때 정의한 여백입니다 (예 : 그림 7 참조). 

경우에 따라 원하는 마진이 아닐 수도 있습니다 (예 : A는 컨테이너 측면에 100dp 마진을, B는 16dp-A 만, A는 사라진 것으로 표시하고 B는 컨테이너에 16dp의 마진을 가짐). 이러한 이유로, 연결이 없어진 것으로 표시되는 위젯에 대한 대체 마진 값을 지정할 수 있습니다 (위의 사라진 마진 속성에 대한 섹션 참조 ).

 

치수 제약ConstraintLayout의 최소 치수

 

ConstraintLayout자체의 최소 및 최대 크기를 정의 할 수 있습니다 .

  • android:minWidth 레이아웃의 최소 너비를 설정
  • android:minHeight 레이아웃의 최소 높이를 설정
  • android:maxWidth 레이아웃의 최대 너비를 설정
  • android:maxHeight 레이아웃의 최대 높이를 설정

최소 및 최대 치수는 ConstraintLayout치수가로 설정 될 때 사용됩니다 WRAP_CONTENT.

 

6. Widgets dimension constraits (치수 제약)

 

View의 가로 세로 사이즈(android:layout_width, android:layout_height)는 크게 3가지 방식으로 결정됩니다.

 

  • 수치를 집적 입력할때 (예를들면 100dp 라고 직접입력하는경우)
  • WRAP_CONTENT를 통해 View스스로 사이즈를 결정 지을 때
  • 0dp를 입력하고 제약조건에의해 사이즈를 결정지을 때. (0dp = MATCH_CONSTRAINT)

 

 

 

그림 8-치수 제약

 

처음 두 가지는 다른 레이아웃과 유사한 방식으로 작동합니다. 

마지막 것은 설정된 제약 조건과 일치하는 방식으로 위젯의 크기를 조정합니다

(그림 8 참조, (a)는 wrap_content, (b)는 0dp). 

여백이 설정되면 계산에서 고려됩니다 (그림 8, (c), 0dp).

 

중요 : ConstraintLayout에서 제약조건 이용시 MATCH_PARENT를 사용하지 않는것을 추천합니다. 대신 left/right 또는 top/bottom 제약조건과 함께 MATCH_CONSTRAINT를 이용하시기 바랍니다.

 

1.1버전에서 WRAP_CONTENT 

 

만약 사이즈에 WRAP_CONTENT를 지정한다면 1.1버전이전에는 말그대로 View스스로 콘텐츠의 사이즈를 동적으로 결정 지었습니다.

레이아웃 밖으로 밀려나가지 않게 하기위해서는 다음 속성을 사용합니다.

  • app:layout_constrainedWidth=”true|false”
  • app:layout_constrainedHeight=”true|false”

 

1.1버전에서 MATCH_CONSTRAINT 

 

가로,세로 길이 입력하는 부분에 0dp(=MATCH_CONSTRAINT)을 적용할 때, 기본적인 동작은 MATCH_PARENT처럼 공간을 부모뷰에 맞게 꽉채우게 됩니다. 하지만 몇몇 속성과 같이 쓴다면 기능이 좀 달라집니다.

 

 

  • layout_constraintWidth_min and layout_constraintHeight_min : WRAP_CONTENT처럼 동작하나 최소값을 가짐
  • layout_constraintWidth_max and layout_constraintHeight_max : WRAP_CONTENT처럼 동작하나 최대값을 가짐
  • layout_constraintWidth_percent and layout_constraintHeight_percent : 0에서 1까지 float 값을 입력하여 비율적으로 길이를 결정

 

 

최소 및 최대min 및 max에 대해 표시된 값은 Dp의 차원이거나 "wrap"일 수 있으며 이는 동일한 값을 사용합니다 WRAP_CONTENT.치수퍼센트를 사용하려면 다음을 설정해야합니다.

 

  • 차원은 MATCH_CONSTRAINT(0dp) 로 설정해야합니다
  • 기본값은 퍼센트 app:layout_constraintWidth_default="percent" 또는app:layout_constraintHeight_default="percent"
  • 그런 다음 layout_constraintWidth_percent 또는 layout_constraintHeight_percent속성을 0과 1 사이의 값으로 설정하십시오.

 

비율

 

위젯의 한 차원을 다른 차원의 비율로 정의 할 수도 있습니다. 그러기 위해서는 적어도 하나의 구속 된 치수를 0dp( MATCH_CONSTRAINT)로 설정하고 속성 layout_constraintDimensionRatio을 주어진 비율로 설정해야합니다 . 

예를 들면 다음과 같습니다.

 

<Button android:layout_width="wrap_content" 
android:layout_height="0dp" 
app:layout_constraintDimensionRatio="1:1" />

 

버튼의 높이를 너비와 동일하게 설정합니다.

 

비율은 다음과 같이 표현 될 수 있습니다.

  • 폭과 높이의 비율을 나타내는 float 치
  • "너비 : 높이"형식의 비율

 

가로 세로를 둘다 MATCH_CONSTRAINT로 적용하는경우 제약조건에 만족하면서 최대한의 크기로 늘려지게 된다. 이때 가로 세로 비율을 결정하고 싶은데 세로기준 또는 가로기준으로 비율을 정하고 싶다면 “H” 또는 “W”를 붙이고 콤마(,)를 찍은뒤 비율을 적어주면됩니다.

 

<Button android:layout_width="0dp" 
android:layout_height="0dp" 
app:layout_constraintDimensionRatio="H,16:9" 
app:layout_constraintBottom_toBottomOf="parent" 
app:layout_constraintTop_toTopOf="parent"/>

 

다음과 같이 코드를 작성하면 세로길이기준으로 16:9인 버튼이 레이아웃에 꽉 차게 됩니다.

 

 

7. Chains 

체인은 단일 축 (수평 또는 수직)에서 그룹과 유사한 동작을 제공합니다. 다른 축은 독립적으로 구속 될 수 있습니다.

 

체인 만들기

한 쌍의 위젯은 양방향 연결을 통해 서로 연결된 경우 체인으로 간주됩니다 (두 개의 위젯이있는 최소 체인을 보여주는 그림 9 참조).

 

그림 9-체인

 

체인 헤드

체인은 체인의 첫 번째 요소 (체인의 "헤드")에 설정된 속성으로 제어됩니다.

 

그림 10-체인 헤드

 

헤드는 가로 체인의 경우 가장 왼쪽에있는 위젯이며 세로 체인의 경우 가장 왼쪽에있는 위젯입니다.

 

체인의 여백

연결에 여백이 지정되면 해당 여백이 고려됩니다. 스프레드 체인의 경우 할당 된 공간에서 마진이 차감됩니다.

 

체인 스타일

chain 스타일은 여러 형태가 존재 할 수 있는데 layout_constraintHorizontal_chianStyle 또는 layout_constraintVertical_chainStyle을 연결된 뷰들의 head에만 적어주면 됩니다. 기본 chain스타일은 CHAIN_SPREAD입니다.

 

  • CHAIN_SPREAD 뷰들을 골고루 펼쳐 여백을 같게 합니다(기본값)
  • CHAIN_SPREAD에서의 Weighted chain은 만약 뷰의 길이가 0dp로 지정되어있다면 남은 공간을 수치만큼 비율적으로 나눠갖습니다.
  • CHAIN_SPREAD_INSIDE CHAIN_SPREAD와 비슷하지만 가장 외곽에 있는 뷰들은 부모 뷰와 여백이 없는 상태로 골고루 펼쳐집니다.
  • CHAIN_PACKED뷰들이 똘똘 뭉치게 되고 부모뷰로부터의 여백을 같게 합니다. 여백을 조정하고 싶다면 bias조정을 통해 한쪽으로 치우치게 만들 수 있습니다.

 

그림 11-체인 스타일

 

가중 체인 

체인의 기본 동작은 사용 가능한 공간에 요소를 균등하게 분산시키는 것입니다. 하나 이상의 요소가를 MATCH_CONSTRAINT사용하는 경우 사용 가능한 빈 공간을 사용합니다 (자체로 동일하게 나눔). 속성 layout_constraintHorizontal_weight및 layout_constraintVertical_weight 공간을 사용하여 요소에 분산되는 방법을 제어합니다 MATCH_CONSTRAINT. 예를 들어,를 사용하여 두 요소를 포함하는 체인 MATCH_CONSTRAINT에서 첫 번째 요소는 가중치 2를 사용하고 두 번째 요소는 가중치 1을 사용하여 첫 번째 요소가 차지하는 공간은 두 번째 요소의 두 배입니다.

 

여백 및 체인 ( 1.1 )

체인의 요소에 여백을 사용하면 여백이 추가됩니다.

예를 들어 가로 체인에서 한 요소가 오른쪽 마진을 10dp로 정의하고 다음 요소가 왼쪽 마진을 5dp로 정의하면 두 요소 사이의 결과 마진은 15dp입니다.

체인이 아이템을 배치하기 위해 사용하는 남은 공간을 계산할 때 아이템과 해당 마진이 함께 고려됩니다. 남은 공간에는 여백이 없습니다.

 

8. Virrual Helper objects  

 

앞에서 설명한 고유 기능 외에도 특수 도우미 개체 ConstraintLayout를 사용하여 레이아웃에 도움을 줄 수 있습니다. 현재 Guideline개체를 사용하면 ConstraintLayout컨테이너를 기준으로 가로 및 세로 안내선을 만들 수 있습니다 . 그런 다음 위젯을 이러한 지침으로 제한하여 위치를 지정할 수 있습니다. 에서 1.1 , Barrier및 Group도 추가되었다.

 

 

최적화 프로그램 ( 1.1 )

 

1.1에서는 제약 조건 최적화 도구를 공개했습니다. app : layout_optimizationLevel 태그 를 ConstraintLayout 요소 에 추가하여 적용 할 최적화를 결정할 수 있습니다 .

 

  • none : 최적화가 적용되지 않습니다
  • standard : 기본값. 직접 및 장벽 제약 조건 만 최적화
  • direct : 직접 제약 조건 최적화
  • barrier : 장벽 제약 조건 최적화
  • chain : 체인 제약 조건 최적화 (실험)
  • dimensions : 치수 측정 값 최적화 (실험), 일치 구속 조건 요소의 측정 값 수 감소

이 속성은 마스크이므로 원하는 최적화를 나열하여 특정 최적화를 켜거나 끌 수 있습니다. 

예 : app : layout_optimizationLevel = "direct | barrier | chain"