0. 종속성 추가
모듈에서 dataBinding
을 enable하기 위해서 app 모듈의 build.gradle의 build option을 true로 설정합니다. 그리고 @Bindable
을 사용하기 위해 plugins에 kotlin-kapt를 추가합니다.
plugins {
...
id 'kotlin-kapt'
}
android {
...
dataBinding {
enabled = true
}
}
1. DataBinding에 대한 기본적인 설명
- [Android/Kotlin] DataBinding
2. Binding Expressions
@={}
와 같이 사용하면 Two-way Binding, @{}
와 같이 사용하면 One-way Binding이라고 합니다. 여기서는 EditText
의 text 속성을 Two-way Binding으로 설정하고, Button
의 onClick 속성을 리스너 결합 방식으로 이벤트를 처리하도록 합니다.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="model"
type="com.naram.weatherproject.ui.main.TextModel" />
</data>
<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"
android:layout_marginVertical="5dp"
android:background="@drawable/item_background"
android:padding="10dp">
<LinearLayout
android:id="@+id/llSearchBar"
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal"
android:weightSum="5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0">
<EditText
android:id="@+id/etSearchCity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="5dp"
android:layout_weight="1.2"
android:fontFamily="@font/nsr_regular"
android:hint="원하는 도시를 검색해보세요."
android:singleLine="true"
android:text="@={model.etSearchCity}"
android:textSize="15sp" />
<Button
android:id="@+id/btnSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="3.8"
android:fontFamily="@font/nsr_bold"
android:onClick="@{() -> model.clickSearchButton()}"
android:text="검색"
android:textSize="15sp" />
</LinearLayout>
<TextView
android:id="@+id/tvCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:fontFamily="@font/nsr_extrabold"
android:text="@={model.tvCity}"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@id/tvTemperature"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="CITY" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3-1. Observable POJO Class 생성
먼저, BaseObservable
을 상속받아야 합니다. 그 후에 Two-way Binding을 할 변수의 Getter와 Setter를 선언합니다. 이때 Getter의 위에 @Bindable
을 추가하고, Build를 하면, BR이라는 클래스 안에 값들이 들어가게 됩니다. 그리고 Setter에는 값이 변경되었을 때 알려줄 수 있도록 notifyPropertyChanged()
를 추가하고, 매개변수로 BR.text
와 같이 넘겨줍니다.
그리고 버튼이 클릭되면 text가 변경되도록 아래 onClickButton
에서 setText()
로 String을 넘겨줍니다.
- TextModel.kt
class TextModel : BaseObservable() {
private var etSearchCity: String? = ""
private var tvCity: String? = ""
fun setEtSearchCity(etSearchCity: String) {
this.etSearchCity = etSearchCity
notifyPropertyChanged(BR.etSearchCity)
}
@Bindable
fun getEtSearchCity(): String? {
return etSearchCity
}
fun setTvCity(tvCity: String) {
this.tvCity = tvCity
notifyPropertyChanged(BR.tvCity)
}
@Bindable
fun getTvCity(): String? {
return TvCity
}
fun onClickButton() {
getEtSearchCity()?.let {
setTvCity(it)
}
}
}
- MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.setVariable(BR.model, TextModel())
}
}
3-2. ObservableField 사용
ObservableField
는 Observable 인터페이스를 구현하지 않고도 속성을 notify할 수 있는 수단을 제공합니다. set()
, get()
접근자 메서드를 사용하며, 값이 변경되면 자동으로 View에 notify하기 때문에 UI를 업데이트할 수 있습니다.
- TextModel.kt
class TextModel {
var etSearchCity: ObservableField<String> = ObservableField("")
var tvCity: ObservableField<String> = ObservableField("")
fun onClickButton() {
etSearchCity.get()?.let {
tvCity.set(it)
}
}
}
- MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.setVariable(BR.model, TextModel())
}
}
'Programando > Android' 카테고리의 다른 글
[Android/Kotlin] Hilt (0) | 2022.05.22 |
---|---|
[Android/Kotlin] RxJava와 RxJava를 이용한 EventBus 구현 (0) | 2022.05.04 |
[Android/Kotlin] SharedFlow를 이용한 EventBus 구현 (0) | 2022.04.17 |
[Android/Java] Retrofit2를 통해 RestAPI와 통신하기 (0) | 2022.03.17 |
[Android/Kotlin] DI(Dependency Injection) (0) | 2022.03.16 |