데이터 바인딩 - 좋아요 카운트 앱 만들어보기
2023. 2. 16. 01:42ㆍAndroid Jetpack
- 화면에는 일부 데이터가 표시되며 사용자가 좋아요 를 클릭하여 카운터를 늘리고 진행률 을 업데이트할 수 있습니다
- 1. 데이터 바인딩 레이아웃으로 변환을 선택합니다.
- 2. 이제 레이아웃이 아래와 같이 보여진다.
<?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.example.databinding.viewmodel.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:minWidth="50dp"
android:minHeight="50dp"
app:layout_constraintBottom_toTopOf="@id/progressBar"
app:layout_constraintStart_toStartOf="@id/progressBar"
app:popularityIcon="@{viewmodel.popularity}" />
<TextView
android:id="@+id/likes_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="@string/likes"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewmodel.likes.toString()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toStartOf="@id/plusbutton"
app:layout_constraintTop_toBottomOf="@id/textview" />
<Button
android:id="@+id/plusbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="@string/Like"
app:layout_constraintStart_toEndOf="@id/textview"
app:layout_constraintTop_toBottomOf="@id/textview" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:max="@{100}"
app:layout_constraintBottom_toTopOf="@+id/textview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:progressScaled="@{viewmodel.likes}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
- Viewmodel
package com.example.databinding.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
enum class Popularity {
NORMAL,
POPULAR,
STAR
}
class MyViewModel
: ViewModel() {
private val _likes = MutableLiveData(0)
val likes: LiveData<Int> = _likes
val popularity =Transformations.map(_likes) {
when {
(it > 50) -> Popularity.STAR
(it > 10) -> Popularity.POPULAR
else -> Popularity.NORMAL
}
}
fun onLike(number:Int) {
_likes.value = _likes.value?.plus(number)
}
}
var _likes는 이 값이 변경될때 ui를 업데이트하는 대신 관찰 가능하게 만듭니다.
Transformation 변환을 사용하여 LiveData를 다른 LiveData에 종속 시킬수 있다.
사용하면 값이 변경될 때 라이브러리가 UI를 업데이트할 수 있습니다.
- BindingAdapter
바인딩 어댑터를 사용하여 사용자 지정 특성을 만들도록합니다.
package com.example.databinding.viewmodel
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.widget.ImageView
import android.widget.ProgressBar
import androidx.core.content.ContextCompat
import androidx.core.widget.ImageViewCompat
import androidx.databinding.BindingAdapter
import com.example.databinding.R
@BindingAdapter(value = ["app:progressScaled", "android:max"], requireAll = true)
fun setProgress(progressBar: ProgressBar, counter: Int, max: Int) {
progressBar.progress = (counter * 2).coerceAtMost(max)
}
@BindingAdapter("app:popularityIcon")
fun popularityIcon(view: ImageView, popularity: Popularity) {
val color = getAssociatedColor(popularity, view.context)
ImageViewCompat.setImageTintList(view, ColorStateList.valueOf(color))
view.setImageDrawable(getDrawablePopularity(popularity, view.context))
}
private fun getAssociatedColor(popularity: Popularity, context: Context): Int {
return when (popularity) {
Popularity.NORMAL -> ContextCompat.getColor(context,R.color.black)
Popularity.POPULAR -> ContextCompat.getColor(context, R.color.popular)
Popularity.STAR -> ContextCompat.getColor(context, R.color.star)
}
}
private fun getDrawablePopularity(popularity: Popularity, context: Context): Drawable? {
return when (popularity) {
Popularity.NORMAL -> {
ContextCompat.getDrawable(context, R.drawable.baseline_people_24)
}
Popularity.POPULAR -> {
ContextCompat.getDrawable(context, R.drawable.baseline_whatshot_24)
}
Popularity.STAR -> {
ContextCompat.getDrawable(context, R.drawable.baseline_whatshot_24)
}
}
}
진행률 값의 경우 최대 값과 좋아요 수를 취하는 바인딩 어댑터를 사용합니다.
package com.example.databinding
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.example.databinding.databinding.ActivityMainBinding
import com.example.databinding.viewmodel.MyViewModel
class MainActivity : AppCompatActivity() {
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
myViewModel = ViewModelProvider(this)[MyViewModel::class.java]
binding.lifecycleOwner = this
binding.viewmodel = myViewModel
binding.plusbutton.setOnClickListener {
val input = binding.editText.text.toString().toInt()
myViewModel.onLike(input)
}
}
}
LiveData는 수명주기 인식 관찰 가능 개체이므로 사용할 수명 주기 소유자를 지정해야합니다.
Edittext에 숫자값을 입력해 좋아요 버튼 을 눌럿을때 좋아요 수가 증가한다.
- 좋아요 50개로 채우기
- 좋아요 갯수에 따라 색상 변경
'Android Jetpack' 카테고리의 다른 글
계산기 만들어보기 (Livedata+ViewModel+DataBinding+BindingAdapter) (0) | 2023.02.15 |
---|---|
코루틴 Flow와 StateFlow (0) | 2023.01.30 |
Room DB를 UI와 연동하기 (0) | 2023.01.30 |
책 검색결과 저장을 위한 Room DB 구현해보기 (0) | 2023.01.27 |
Safe args로 Fragment 간 데이터 전달하기 (1) | 2023.01.26 |