
he Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
val factory = MyViewModelFactory(100,this)
val myViewModel by viewModels<MyViewModel>(){factory}
binding.lifecycleOwner = this
binding.viewmodel = myViewModel
binding.textView.text = myViewModel.counter.toString()
binding.button.setOnClickListener {
myViewModel.liveCounter.value = myViewModel.liveCounter.value?.plus(1)
}
}
}
<?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:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.getupmina.android.databinding.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewmodel.modifiedCounter.toString()}"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:text="Increase"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
package com.getupmina.android.databinding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import com.getupmina.android.databinding.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
val factory = MyViewModelFactory(10,this)
val myViewModel by viewModels<MyViewModel>(){factory}
binding.lifecycleOwner = this
binding.viewmodel = myViewModel
binding.button.setOnClickListener {
myViewModel.liveCounter.value = myViewModel.liveCounter.value?.plus(1)
}
}
}
package com.getupmina.android.databinding
import android.widget.ProgressBar
import androidx.databinding.BindingAdapter
@BindingAdapter("app:progressScaled")
fun setProgress(progressBar: ProgressBar, counter: Int) {
progressBar.progress = counter
//app:progressScaled가 값을 전달받을 떄마다 BindingAdapter에서는 자동으로 setProgress함수가 실행되게 된다.
}
package com.getupmina.android.databinding
import android.widget.ProgressBar
import androidx.databinding.BindingAdapter
@BindingAdapter(value = ["app:progressScaled","android:max"],requireAll = true)
fun setProgress(progressBar: ProgressBar, counter: Int, max: Int) {
progressBar.progress = (counter * 2).coerceAtMost(max)
} app:progressScaled 와 android:max 를 동시에 관찰하면서 변화가 있을 때 progressbar의 증가량을 counter값의 2배로 하되, max값 이상이 되지 않도록 한다.<?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:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.getupmina.android.databinding.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Increase"
android:layout_margin="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:max="@{100}"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.3"
app:progressScaled="@{viewmodel.liveCounter}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
package com.getupmina.android.databinding
import androidx.lifecycle.*
class MyViewModel(_counter: Int, private val savedStateHandle: SavedStateHandle) : ViewModel() {
var liveCounter: MutableLiveData<Int> = MutableLiveData(_counter)
var counter:Int = savedStateHandle.get<Int>(SAVE_STATE_KEY)?:_counter
val modifiedCounter : LiveData<String> = Transformations.map(liveCounter) { counter ->
"$counter 입니다"
}
val hasChecked : MutableLiveData<Boolean> = MutableLiveData<Boolean>(false)
//null이면 전달받은 초기값을 사용할 수 있도록 설정
fun saveState(){
savedStateHandle.set(SAVE_STATE_KEY,counter)
}
companion object{
private const val SAVE_STATE_KEY = "counter"
} //key를 설정
}
<?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:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.getupmina.android.databinding.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Increase"
android:layout_margin="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:max="@{100}"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.3"
app:progressScaled="@{viewmodel.liveCounter}" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:checked="@={viewmodel.hasChecked}"
android:text="CheckBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
<TextView
android:id="@+id/checkBoxView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="@{viewmodel.hasChecked.toString()}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/checkBox" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
냉동코더의 알기 쉬운 Modern Android Development 입문 강의 - 인프런
출처 : 냉동코더의 알기 쉬운 Modern Android Development 입문
https://github.com/cliearl/book-search-app
Designed and developed by 2022 FrozenCoder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.