데이터 바인딩 – 앱 만들어

  • 화면에 일부 데이터가 표시되고 사용자는 “좋아요”를 클릭하여 카운터를 늘리고 진행 상황을 업데이트할 수 있습니다.

  • 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>


  • 모델 보기
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를 업데이트하는 대신 관찰 가능하게 만듭니다.

변환을 사용하여 하나의 LiveData를 다른 LiveData에 종속시킬 수 있습니다.

이렇게 하면 값이 변경될 때 라이브러리가 UI를 업데이트할 수 있습니다.

  • 바인딩 어댑터

바인딩 어댑터를 사용하여 사용자 정의 속성을 생성할 수 있습니다.

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는 수명 주기를 인식하는 관찰 가능 항목이므로 사용할 수명 주기 소유자를 지정해야 합니다.

좋아요 버튼을 누를 때 좋아요 수를 늘리려면 편집 텍스트에 숫자 값을 입력하십시오.


  • 좋아요 50개로 채우세요
  • 좋아요 수에 따라 색상 변경