Constraint Layout 의 Flow
chapter5 프로젝트를 생성하자.
계산기를 만들 때, 많은 reference 들이 Table Layout 을 사용한다.
그러나 이 챕터에서는 Constraint Layout 의 Flow 를 사용할 것이다.
인터넷에 검색할 때, 안드로이드 Flow 를 키워드로 하면
데이터 흐름을 관리하는 Flow 에 대한 설명을 찾을 수도 있다.
우리는 Constraint Layout의 Flow 에 대해서 이야기하고 있는 것이다.
안드로이드 공식문서에서 Flow 를 찾아보자.
키워드는 다음과 같다.
Virtual Layout
similar to chain
배치를 할 때, constraint_referenced_ids 를 사용
1) VirtualLayout 의 장점
hierarchy 가 flat 하다.
뷰 구조를 flat 하게 만들 수 있다.
뷰의 레이아웃 계층 구조가 flat 할 수록
렌더링하는 속도 ( UI를 그리는 속도 ) 가 빨라진다.
Linear Layout 을 사용하면, UI 를 편하게 그릴 수 있다.
Constraint Layout 처럼 Constraint 관계를 따로 가지지 않아서
특히 쌓는 구조를 그릴 때 편리하다.
단, flat 한 계층구조 권장사항에 위배되기 때문에
유혹을 떨치고 Constraint Layout 으로 돌아오게 된다.
그런데 Constraint Layout 의 Flow 를 사용하면
Linear Layout 의 장점을 가져갈 수 있다.
2) Three Buttons 배치
Flow 가 무엇인지 알아보기 위해
3개의 버튼을 만들어보자.
버튼 스타일 통일을 위해
res 우클릭 > New > Android Resource File 에서
styles.xml 를 만들자.
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="numKeyPad">
<item name="android:textSize">40sp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>
activity_main.xml
<Button
android:id="@+id/button1"
style="@style/numKeyPad"
android:text="1" />
<Button
android:id="@+id/button2"
style="@style/numKeyPad"
android:text="2" />
<Button
android:id="@+id/button3"
style="@style/numKeyPad"
android:text="3" />
Button 배치할 때, Expand 또는 Chain Mode 를 사용할 수 있다.
2-1) [배치] Expand
Organize > Expand Horizontally
결과
각 Button 내부에 constraint 관련 코드가 몇 줄 추가된다.
2-2) [배치] Chains
요소들 드래그 > Chains > Create Horizontal Chain
결과
각 Button 내부에 constraint 관련 코드가 몇 줄 추가된다.
horizontal 로만 constraint 를 지정해주었기 때문에,
vertical constraint 도 지정을 해주어야 한다.
이런식으로 쌓게되는 구조임에도 불구하고
복잡한 UI 를 constraint 으로 만들 수 밖에 없다.
이때 유용하게 사용할 수 있는 것이 Flow 이다.
내부 값을 최대한 사용하기 위해서
layout_width 와 layout_height 를 0dp 로 지정했다.
3) Flow 코드 추가 ( constraint_referenced_ids )
<!-- Flow -->
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:constraint_referenced_ids="button1, button2, button3"
/>
<Button
android:id="@+id/button1"
style="@style/numKeyPad"
android:text="1" />
결과
Button 에서 constraint 를 따로 지정해주지 않았는데
Flow 코드 추가를 하였더니, Button 들이 배치가 되었고
각 Button 내부에 constraint 관련 코드가 없다.
코드가 간결해진 것이다.
Flow 를 사용하므로 constraint 를 추가하지 않아도 된다는 것을 알려주는
missing constraints 무시하는 코드를 추가하자.
tools:ignore="MissingConstraints"
✽ styles.xml 수정
버튼이 떨어져있지 않고 붙어있었으면 좋겠으므로
styles.xml 에서 layout_width 와 layout_height 를
각각 parent 에서 0dp 로 변경하자.
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="numKeyPad">
<item name="android:textSize">40sp</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">0dp</item>
</style>
</resources>
✽456 / 789 추가 ( flow_maxElementsWrap, flow_wrapMode )
이전에 버튼 1, 버튼 2, 버튼 3을 복사/붙이기 해서
456/789 버튼들을 만들어보자.
이렇게 버튼을 만들게 되면 우려스러운 점이
계속 가로로 쌓을 수 있으려면
Flow 가 줄(행) 별로 있어야 한다.
Flow 는 순서에 따라 배치가 된다.
app:constraint_referenced_ids="button1, button3, button2"
이렇다면 버튼 순서는 1, 3, 2
이전에 버튼 1, 2, 3 만 flow 에 있었다면
버튼 4, 5, 6, 7, 8, 9 모두 flow 에 추가해준다.
app:constraint_referenced_ids="button1, button2, button3, button4, button5, button6, button7, button8, button9"
그럼 한 행에 최대 몇 개의 UI 요소를 배치할 지
지정하지 않았기 때문에 아래와 같이 보인다.
이제 한 행에 배치할 뷰의 최대 개수인 flow_maxElementsWrap와
이를 적용하기 위해 반드시 지정해야하는 flow_wrapMode 를 지정하자.
flow_wrapMode 의 기본값은 none 이다.
app:flow_maxElementsWrap="3"
app:flow_wrapMode="aligned"
✽ [flow_wrapMode ] aligned 와 chain, 그리고 chain2
aligned 와 chain 의 차이를 알기 위해서
1번 버튼을 지워보았다.
✽ gap
우리는 aligned 를 옵션으로 할 것이다.
가로로 뷰들 사이 간격을 주기 위해서 horizontal gap 을 지정하자.
app:flow_horizontalGap="8dp"
계산기 키패드 높이를 줄여보자.
app:layout_constraintHeight_percent="0.7"
또 계산기 키패드를 아래로 내리자.
app:layout_constraintVertical_bias="1"
숫자 키패드 색을 변경해보자.
styles.xml
<item name="backgroundTint">@color/teal_200</item>
backgroundTint 를 이용하면, 원래 있던 버튼의 색깔만 변경할 수 있다.
<item name="backgroundColor" 값이 아닌
backgroundTint 를 지정해주었다.
✽ 나머지 버튼 추가
0버튼과 =버튼도 추가해보자.
=버튼 가로길이가 0버튼의 가로길이의 2배가 되도록 아래와 같은 옵션 추가.
layout_constraintHorizontal_weight
<Button
...
android:text="0"
app:layout_constraintHorizontal_weight="1"/>
<Button
android:id="@+id/buttonEqual"
style="@style/numKeyPad"
android:text="="
app:layout_constraintHorizontal_weight="2"
tools:ignore="MissingConstraints" />
이제 clear버튼과 +버튼, -버튼을 추가해야한다.
위 버튼은 3버튼, 6버튼, 9버튼 오른쪽에 추가하고 싶으므로,
행 최고 요소 개수를 4로 변경하자.
app:flow_maxElementsWrap="4"
app:constraint_referenced_ids= "button1, button2, button3, buttonClear,
button4, button5, button6, buttonPlus,
button7, button8, button9, buttonMinus
,button0, buttonEqual"
행 내 최대 4개 요소로 변경되었으므로
weight 를 1:3 으로 변경하자.
<Button
...
android:text="0"
app:layout_constraintHorizontal_weight="1"/>
<Button
android:id="@+id/buttonEqual"
style="@style/numKeyPad"
android:text="="
app:layout_constraintHorizontal_weight="3"
tools:ignore="MissingConstraints" />
마지막으로 연산자 버튼들만 색을 변경해보자.
styles.xml
<style name="operatorKeypad" parent="numKeyPad">
<item name="backgroundTint">@color/teal_700</item>
</style>
3) 전체 코드
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- Flow -->
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/keyPadFlow"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHeight_percent="0.7"
app:layout_constraintVertical_bias="1"
app:flow_maxElementsWrap="4"
app:flow_wrapMode="chain"
android:padding="8dp"
app:flow_horizontalGap="8dp"
app:constraint_referenced_ids="button1, button2, button3, buttonClear, button4, button5, button6, buttonPlus, button7, button8, button9, buttonMinus
,button0, buttonEqual"
/>
<Button
android:id="@+id/button1"
style="@style/numKeyPad"
android:text="1"
tools:ignore="MissingConstraints"/>
<Button
android:id="@+id/button2"
style="@style/numKeyPad"
android:text="2"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button3"
style="@style/numKeyPad"
android:text="3"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button4"
style="@style/numKeyPad"
android:text="4"
tools:ignore="MissingConstraints"/>
<Button
android:id="@+id/button5"
style="@style/numKeyPad"
android:text="5"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button6"
style="@style/numKeyPad"
android:text="6"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button7"
style="@style/numKeyPad"
android:text="7"
tools:ignore="MissingConstraints"/>
<Button
android:id="@+id/button8"
style="@style/numKeyPad"
android:text="8"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button9"
style="@style/numKeyPad"
android:text="9"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/button0"
style="@style/numKeyPad"
android:text="0"
app:layout_constraintHorizontal_weight="1"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonEqual"
style="@style/operatorKeypad"
android:text="="
app:layout_constraintHorizontal_weight="3"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonClear"
style="@style/operatorKeypad"
android:text="C"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonPlus"
style="@style/operatorKeypad"
android:text="+"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/buttonMinus"
style="@style/operatorKeypad"
android:text="-"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
'안드로이드 앱(Kotlin|Java) > [2025~] 안드로이드 앱' 카테고리의 다른 글
Part1_Ch05_04 계산 기능 구현하기(2) (0) | 2025.04.09 |
---|---|
Part1_Ch05_03 계산 기능 구현하기(1) (0) | 2025.04.09 |
Part1_Ch05_01 개요 및 학습목표 (0) | 2025.04.09 |
Part1_Ch04_09 복습 및 한걸음 더 (1) | 2025.04.09 |
Part1_Ch04_08 전화 앱 실행하기 (0) | 2025.04.09 |