Android Jetpack

계산기 만들어보기 (Livedata+ViewModel+DataBinding+BindingAdapter)

wdadaww 2023. 2. 15. 00:11

+,-  버튼을 만들어서  Edittext에 숫자를 넣고 실시간으로 계산된 값을 보여주는 계산기를 Livedata와 Databinding을 이용해보겟습니다.

 

  • activity_main_xml
<?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.viewmodel.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.mapCounter.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/minusbutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="빼기"
            app:layout_constraintTop_toBottomOf="@id/textview"
            app:layout_constraintEnd_toEndOf="parent"/>

        <Button
            android:id="@+id/plusbutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="더하기"
            app:layout_constraintEnd_toStartOf="@id/minusbutton"
            app:layout_constraintTop_toBottomOf="@id/textview" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

EditText에 숫자를 넣고 더하기 ,빼기 버튼을 누르면 계산된 값을 TextView로 보여주는  간단히 계산기 UI 만들어 보았습니다.

 

 

  • ViewModel 클래스
package com.example.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel

enum class ButtomState {
    Plus, Minus
}


class MyViewModel

    : ViewModel() {

    private val liveCounter = MutableLiveData(0)


    val mapCounter = Transformations.map(liveCounter) { Counter ->
        "${Counter}입니다"
    }

    fun liveDataCounter(state: ButtomState, number: Int) {
        when (state) {
            ButtomState.Plus ->
                liveCounter.value = liveCounter.value?.plus(number)
            ButtomState.Minus ->
                liveCounter.value = liveCounter.value?.minus(number)
        }
    }
}

liveDataCounter 함수를 보면 버튼의 상태에따라 MutableLivedata의 값을 새롭게 초기화해주고있다.

 

  • MainActivity
package com.example.viewmodel

import android.os.Bundle
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.example.viewmodel.databinding.ActivityMainBinding

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]

        //LiveData를 관측하기위해 lifecycleowner정의
        //xml 데이터뷰를 가지고있는 viewmodel 를지정.
        binding.lifecycleOwner = this
        binding.viewmodel = myViewModel

        // ViewModel + Livedata 적용
        binding.plusbutton.setOnClickListener {
            val input = binding.editText.text.toString().toInt()
            myViewModel.liveDataCounter(ButtomState.Plus, input)

            binding.minusbutton.setOnClickListener {
            val input = binding.editText.text.toString().toInt()
                myViewModel.liveDataCounter(ButtomState.Minus, input)
            }
        }
    }
}

버튼 setOnClickListener를 통해 ViewModel에서 구현했던 데이터를 업데이트해주는 liveDataCounter 함수를 호출 해주면된다.

  • 결과물

 

 

  • 바인딩 어댑터를 사용하여 사용자 지정 특성 만들기
  • activity_mainl.xml에 프로그래스바 를 추가해준다

  • BindingAdapter 클래스를 만들어줍니다.
package com.example.viewmodel.adapter

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)
}