일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 클린아키텍처
- Flow
- 커스텀뷰
- 코딩테스트
- 회원가입
- MVVM
- Jetpack
- UiState
- 코틀린
- coroutine
- 뷰
- 컴포즈
- Authentication
- 안드로이드
- Android
- 플레이스토어
- DiffUtil
- 로그인
- 알고리즘
- XML
- sharedFlow
- Kotlin
- 파이어베이스
- NavController
- Build variants
- 리사이클러뷰
- ListAdapter
- NavHost
- Compose
- cleanarchitecture
- Today
- Total
Grusie 안드로이드 개발 기술 블로그
[Android] Data binding 기본 사용법 및 BindingAdapter 본문
기존에 미라클알람 프로젝트를 진행하며 데이터바인딩에 대해 찍먹 정도는 해 본 적이 있다. 그 때는 잘 모르는 상태로 진행하여 코드도 난잡하고 사용하기 힘들었었고, 회사 프로젝트에 사용하려고 해 보았으나, data binding이 패키지명에 대문자가 있으면 에러가 나는 것 같았다. 하필 회사 프로젝트의 패키지명이 대문자로 되어있어 적용을 포기했었던 것 같다. 그 이후로 뷰바인딩만 사용하였고, 컴포즈 공부를 하면서, Data binding을 서서히 잊어갔다... xml의 사용을 줄이기위해 컴포즈로 공부하고 있었는데, 데이터바인딩은 오히려 XML에서 로직까지 사용하여 분리가 불가능 하게 될 것이라는 생각 때문이였다.
그러나 이번에 메모리즈 프로젝트를 진행하는데, 기존에 계셨던 분이 데이터바인딩으로 코드를 구현 해두었기에, 한 번 기술스택에 본인을 맞춰봐야겠다고 생각이 들었다.
데이터바인딩 기본 사용법
의존성 추가
모듈수준의 build.gradle에 dataBinding 사용 설정을 해준다.
android {
. . .
dataBinding {
enabled = true
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="backgroundColor"
type="String" />
</data>
...
</layout>
XML의 영역을 <layout> 태그로 감싼다.
<layout>태그 안에 필요한 데이터를 넣을 <data> 태그를 삽입하고, 원하는 변수의 이름과 타입을 지정하는 <variable>을 사용할 수 있다.
Class타입의 변수
<variable
name="viewModel"
type="com.example.memories.ui.main.calendar.CalendarViewModel" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.getCalendarAccountInfo()}"/>
이런식으로 하위 함수를 호출하는 형태로도 사용이 가능하다.
import 및 삼항연산자
<import type = "android.view.View"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{text != null ? View.VISIBLE : View.GONE}"/>
추가로 필요한 import문이 있다면 import태그로 추가가 가능하고, 삼항 연산자도 사용이 가능하다.
코드
private val binding by lazy {ActivityMainBinding.inflate(layoutInflater)}
원하는 곳에서 뷰바인딩과 마찬가지의 형태로 binding 선언을 해주고, 데이터를 입력 할 때에는, binding.text 이런 변수 형태로 넣어주면 된다.
여기까지 간단한 데이터 바인딩에 대해 알아 보았고, 로직이 들어가는 데이터 바인딩을 처리하는 방법을 소개하겠다.
BindingAdapter를 활용하는 방법이다.
BindingAdapter 사용법
object BindingAdapter {
@JvmStatic
@BindingAdapter("app:hexToColor")
fun setColor(view: View, hex: String){
try {
view.setBackgroundColor(Color.parseColor(hex))
} catch (e:Exception) {
view.setBackgroundColor(Color.TRANSPARENT)
}
}
}
우선 따로 생성자를 통해 생성할 필요 없도록 object에 만들어서 메모리에 올려두자.
@BindingAdapter 어노테이션을 통해, 원하는 속성 명을 지정해주고, 함수 내부에서 로직을 작성하면 된다.
view는 기본으로 가져가고, String타입인 색상 핵사코드를 가지고, Color로 변환시켜 배경 이미지를 바꾸는 방법이다.
파라미터를 여러개 사용할 경우
@JvmStatic
@BindingAdapter("app:version", "app:isVisible", requireAll = false)
fun setVersion(view: TextView, version: String? = "", isVisible:Boolean?= false){
view.run {
visibility = if(isVisible == true) View.VISIBLE else View.GONE
text = "version : $version"
}
}
여러 데이터를 가지고 데이터 처리를 하려면, BindingAdapter에 파라미터를 더 추가하고, 그에 맞는 로직을 작성하면 된다.
requireAll은 속성들이 반드시 전부 필요한지에 대해 설정하는 변수이다.
XML
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="393dp"
android:background="@color/green_6BB53D"
app:hexToColor="@{backgroundColor}">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="40sp"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
app:version="@{version}"
app:isVisible="@{isVisible}" />
이렇게 생성한 속성을 XML에서 사용하려면 이렇게 사용하면 된다.
생생한 차이를 위해, 기존 백그라운드를 녹색으로 해두고, TextView의 visibility를 gone으로 해두었다.
코드
class EditRecordActivity : AppCompatActivity() {
val binding: ActivityEditRecordBinding by lazy {
ActivityEditRecordBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.run {
cardViewBackground = "#ff0000"
version= "1.0.0"
isVisible = true
}
}
}
이렇게 사용하면 원하는 결과가 나올 것이다.
결과
참고
https://salmonpack.tistory.com/44
https://todaycode.tistory.com/53
https://markim94.tistory.com/163
후기
솔직히 데이터바인딩의 필요성을 크게 느끼진 못하겠다. 코드의 가독성을 위함..? 아니면 뷰의 상태를 일관되게 유지? 흠.. 물론 LiveData로 옵저빙하여 변수를 하나씩 사용한다면 큰 의미가 있을 거 같기도 한데, StateFlow와 sealed class로 UiState를 만들어 관리한다면, 데이터바인딩으로 하는 것 보다 코드에서 하는 게 더 가독성이 좋을 것이라고 생각한다. 그래서 요즘은 viewBinding만 활용한다는 것 같으나, 이런 기술들도 사용 할 줄은 알아야 한다고 생각한다.
'안드로이드 개발 > 라이브러리' 카테고리의 다른 글
[Android] 네이버 맵 공식 클러스터링 적용법 (0) | 2024.06.12 |
---|---|
[Android] DataStore 사용하기(HashMap형태 저장) (0) | 2024.05.23 |
[Android] 이미지 로딩 라이브러리 Glide, Fresco (Glide를 사용한 이유) (1) | 2024.04.19 |
[Android]RxJava 사용하기 (0) | 2024.04.15 |
[Android] Retrofit2 사용법 (0) | 2024.03.27 |