일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 플레이스토어
- 모의고사
- 내신
- customdialog
- 유니티
- 과탐
- MNIST
- 생명과학
- 코틀린
- 개발일지
- Firebase
- 수능
- JavaScript
- 고등학교
- PoLAB
- 포랩
- 1등급사과
- 생명과학1
- 수학가형21번
- 개발
- 바른생수
- 고등학생
- Android
- 딥러닝
- 수학가형
- ios
- LineRenderer
- Unity
- kotlin
- xcode
- Today
- Total
수학적 접근
[Android/Kotlin] XML Data Binding 본문
Android에서 레이아웃을 만들 때, 똑같은 모양을 반복해서 그려야 할 때가 있습니다.
그럴 때는 보통 반복되는 부분을 따로 레이아웃을 만든 다음(child),
원 파일(parent)에 이 child를 <include>를 사용하여 가져오는 방식으로 코드의 재사용성을 높여주는 것이 바람직합니다.
그런데 똑같은 모양이 반복되기는 하지만, child 안에 들어가는 세부적인 내용이 조금씩 다르다면 어떻게 할까요?
예를 들어 텍스트 글자 하나만, 배경색 하나만 다르다면?
이 정도 차이 때문에 일일이 따로 만들기에는 꽤 시간낭비라고 느껴질 수 있습니다.
그래서 이렇게 차이나는 부분만을 변수로 만들어서, parent 단에서 값을 지정해주는 방법이 있습니다.
아래에서는 이 방법을 사용하는 예제를 볼 것입니다.
이 예제에서 구현할 모양은 아래와 같습니다.
하나의 child 요소를 만들어서 총 세 번 재사용을 하며,
달라지는 요소는
1. 과일 이름
2. 과일 이미지
3. 과일 색
4. 배경색
네 가지입니다.
이를 구현하기 위해서
1. 텍스트 (String)
2. 그림 (Drawable)
3. 색 (ColorInt)
세 가지 종류의 데이터를 전달해야 합니다.
참고로 이외 다른 종류의 데이터도, 이 예제에서 사용하는 방법과 비슷한 방법을 사용한다면 전달할 수 있습니다.
(이를테면, 직접 정의한 클래스도 사용할 수 있습니다)
그럼 전체 코드를 보면서 설명하겠습니다.
---- 들어가기 전에 ----
* 이 방법을 적용하기 위해서는 아래 설정이 필요합니다.
app 수준의 build.gradle
파일에서 아래 내용을 추가합니다.
android {
. . .
dataBinding {
enabled = true
}
}
작성 후 Sync 를 해줍니다.
* 여기에서 사용된 과일 svg 파일입니다.
----------------
element_fruit.xml (child)
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="backgroundColor" type="Integer" />
<variable name="fruitIcon" type="android.graphics.drawable.Drawable" />
<variable name="fruitColor" type="Integer" />
<variable name="fruitName" type="java.lang.String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:padding="8dp"
android:background="@{backgroundColor}"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:layout_gravity="center"
app:colorFilter="@{fruitColor}"
android:src="@{fruitIcon}" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:textSize="16sp"
android:textColor="@color/black"
android:text="@{fruitName}"/>
</LinearLayout>
</layout>
child 요소에 대한 xml 코드입니다.
전체를 <layout />
요소로 감싸주었고, <data />
요소를 이용하여 필요한 변수 4개 및
각각의 데이터 타입을 정의해주었습니다.
평소 구현할 때와 한 가지 다른 점이 있는데,
평소에는 svg 파일의 색상을 변경할 때 app:tint
라는 필드를 사용합니다.
그런데 이렇게 데이터 전달을 할 때에는 app:colorFilter
라는 것을 사용하여야
정수 값을 이용하여 간단하게 색상 값을 전달할 수 있습니다.
app:tint
가 받을 수 있는 데이터 타입이 정확하게 어떤 것인지 파악이 되지 않는데, 정수나 문자열을 받지 못하는 것으로 보아
app:tint
필드를 그대로 사용하려면 복잡한 과정을 거쳐야 할 것으로 보입니다.
이를 이용하여 parent를 구현하면 아래와 같습니다.
activity_main.xml (parent)
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/element_fruit"
bind:backgroundColor="@{@color/apple_background}"
bind:fruitIcon="@{@drawable/ic_apple}"
bind:fruitColor="@{@color/apple}"
bind:fruitName="@{@string/apple}"
/>
<include
layout="@layout/element_fruit"
bind:backgroundColor="@{@color/banana_background}"
bind:fruitIcon="@{@drawable/ic_banana}"
bind:fruitColor="@{@color/banana}"
bind:fruitName="@{@string/banana}"
/>
<include
layout="@layout/element_fruit"
bind:backgroundColor="@{@color/grape_background}"
bind:fruitIcon="@{@drawable/ic_grape}"
bind:fruitColor="@{@color/grape}"
bind:fruitName="@{@string/grape}"
/>
</LinearLayout>
</layout>
변수에 대입될 값들은
values/strings.xml
values/colors.xml
에 각각 정의하여 적용하였습니다.
그리고 값을 전달할 때 기존에 ConstraintLayout
등에서 볼 수 있는 app
이란 xml namespace와 동일한 것을
bind
라는 namespace를 굳이 다시 정의해서 사용하는데,
저는 기존의 app
과 제가 직접 정의한 변수를 구분지어주는 것을 선호하기 때문에 이런 짓을 합니다.
원래는
app:backgroundColor
app:fruitIcon
...
으로 작성해도 무방합니다.
이렇게 두 파일을 작성해주면 앞에서 보여드렸던 모양을 구현할 수 있습니다.
이상 구현한 내용을 github에 올려두었습니다.
만약 values/strings.xml
, values/colors.xml
파일이 필요하시다면 git을 확인해보시기 바랍니다.
참고
1. 만약 @string/apple
과 같이 미리 정의된 값을 사용하지 않고 직접 "사과"
와 같이 대입하고자 하는 경우,
@string/apple
을 "사과"
로 대체하는 것은 성공하지만, @color/apple
을 "#ff0000"
로 대체하는 것은 실패합니다.
약간의 추가 작업이 필요한데, 이에 대한 글을 작성할 예정입니다.
2. 이렇게 정의한 4개의 변수들은 코틀린 코드에서도 활용할 수 있습니다.
직접 정의한 변수를 코틀린 코드에서 활용하는 방법에 대한 글을 작성할 예정입니다.
'개발 > Android' 카테고리의 다른 글
[Android/Kotlin] Custom Dialog 만들기 (NEW) (1) | 2022.03.03 |
---|---|
[Android/Kotlin] Custom Dialog 만들기 (3) | 2020.02.07 |