시작하기
본 글에서는 Fragment에서 데이터 바인딩을 사용하는 방법에 대해서 알어보도록 한다.
데이터 바인딩의 기본 사용 방법은 이전글을 참고한다.
Fragment 생성
안드로이드 스튜디오에서 빈 플레그먼트를 생성하면 자동으로 코드가 생성된다. 바인딩 객체는 UI를 초기화하는 시점인 onCreateView 콜백 함수에서 초기화할 수 있다.
- 기존 소스코드
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false)
}
- 데이터 바인딩 소스코드
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding: FragmentCounterBinding =
DataBindingUtil.inflate(inflater, R.layout.fragment_counter, container, false)
val view = binding.root
return view
}
Full Source
build.gradle (:app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.sungje365.fragmenttest"
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
dataBinding true
}
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
def lifecycle_version = "2.3.1"
def fragment_version = "1.3.5"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycle
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// Fragment
implementation "androidx.fragment:fragment-ktx:$fragment_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.view.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/frag_main"
android:name="com.sungje365.fragmenttest.ui.view.CounterFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_counter.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.sungje365.fragmenttest.ui.viewmodel.CounterViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.view.CounterFragment">
<TextView
android:id="@+id/tv_frag_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(viewModel.counter)}"
android:textSize="100sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/tv_frag_count"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<Button
android:id="@+id/btn_frag_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/all_add"
android:onClick="@{() -> viewModel.increase()}" />
<Button
android:id="@+id/btn_frag_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/all_sub"
android:onClick="@{() -> viewModel.decrease()}" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainActivity.kt
package com.sungje365.fragmenttest.ui.view
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.sungje365.fragmenttest.R
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
CounterFragment.kt
package com.sungje365.fragmenttest.ui.view
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.sungje365.fragmenttest.R
import com.sungje365.fragmenttest.databinding.FragmentCounterBinding
import com.sungje365.fragmenttest.ui.viewmodel.CounterViewModel
class CounterFragment : Fragment() {
private lateinit var binding: FragmentCounterBinding
private val model: CounterViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_counter,
container,
false
)
binding.apply {
viewModel = model
lifecycleOwner = this@CounterFragment
}
return binding.root
}
}
CounterViewModel.kt
package com.sungje365.fragmenttest.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class CounterViewModel : ViewModel() {
val counter: MutableLiveData<Int> by lazy { MutableLiveData<Int>() }
init {
viewModelScope.launch {
counter.value = 0
}
}
fun increase() {
counter.value = counter.value?.plus(1)
}
fun decrease() {
counter.value = counter.value?.minus(1)
}
}
'Android > Data Binding' 카테고리의 다른 글
[데이터 바인딩] DataBinding 사용하기 (0) | 2021.07.02 |
---|