본문 바로가기
안드로이드

[안드로이드/Kotlin] MVVM응용 - 번호 뽑기 만들기

by krapoi 2022. 3. 18.
반응형

내가 MVVM을 연습하면서 번호 뽑기 앱을 만들어 보았다.

 

이걸 만들고 나니 MVVM을 생각보다 쉽게 사용하게 된 것 같다.

일단

먼저 폴더를 나누어 주었다.

 

그다음 gradle을 정의해 주었다.

이건 저번에 사용한 라이브 데이터와 데이터 바인딩과 같다.

android {
...

    dataBinding {
        enabled = true
    }
}


dependencies {

...

    def lifecycle_version = "2.2.0"

    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
    implementation "androidx.activity:activity-ktx:1.4.0"
    implementation 'androidx.fragment:fragment-ktx:1.4.1'
    }

 

이제 코드로 가보자.

맨 처음 module에서 Database를 만들어 주었다.

내가 만들 기능들을 미리 생각해서 만들어 주었다.

class Database {

    private lateinit var database : Database
    private var arrayList : ArrayList<Int> = ArrayList() // arraylist 초기화

    fun saveNumber(number:Int){
        arrayList.add(number)
    }

    fun getAllNumber(): ArrayList<Int> {
        return arrayList
    }

    fun removeNumber(){
        arrayList.clear()
    }

}

ArrayList를 하나 생성해서 번호를 저장하고, 이때까지 뽑은 번호를 다 보여줄 수 있게 만들었다.

그러기 위해서 먼저 모듈에 숫자를 저장하는 함수를 하나 만들었고, ArrayList전체를 반환하는 함수를 하나 만들었다.

그리고 삭제 기능까지.

 

그다음은 viewModel에서 MainViewModel을 만들어 주었다.

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pick_up_game.module.Database
import java.util.*
import kotlin.collections.ArrayList

class MainViewModel : ViewModel() {

    private val database: Database = Database()

    private var rand = Random()

    var nowNum = -1

    companion object{
        var MaxNum = 101
    }

    var text: MutableLiveData<String> = MutableLiveData()

    init {
        text.value = ""
    }
    fun getNum(){
        nowNum = rand.nextInt(MaxNum) + 1
        database.saveNumber(nowNum)
        text.value = nowNum.toString()
    }

    fun setMaxNum(int: Int?){
        println(int)
        MaxNum = int!!
    }

    fun showAllNum() {
        if (nowNum == -1)
            return

        text.value = ""
        var array: ArrayList<Int> = ArrayList()

        array = database.getAllNumber()


        for (i in 0 until array.size) {
            text.value += array.get(i).toString() + " "
        }

        println(text)

    }
}

 데이터베이스를 인스턴스 시켰고, 값을 랜덤 하게 뽑아야 하기 때문에 Random함수를 불러와 줬다.

지금 번호는 먼저 -1로 정해두었고 -1인 상태에서 내가 뽑은 수 전부 보기를 누르면 아무것도 나오지 않게 만들었다.

그다음 최대수는 companion object로 static 상태로 만들어 주었다.

마지막으로 표시할 text를 livedata로 만들었다.

 

나머지 함수들은 그렇게 이해하기 어려운 부분은 아닐 것이다.

어쨌든 실제로 동작할 기능들을 만들었으니 이제, view로 넘어가 보자.

 

일단 view가 2개 있는데 MainActivity부터 살펴보자

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import com.example.pick_up_game.R
import com.example.pick_up_game.databinding.ActivityMainBinding
import com.example.pick_up_game.viewModel.MainViewModel

class MainActivity : AppCompatActivity() {

    private lateinit var mbiniding : ActivityMainBinding
    private val model : MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mbiniding = DataBindingUtil.setContentView(this,R.layout.activity_main)

        mbiniding.lifecycleOwner = this
        mbiniding.viewModel = model

        var SetMaxnum = findViewById<Button>(R.id.setMaxNumbtn)

        SetMaxnum.setOnClickListener{
            var intent = Intent(this, SetMaxActivity::class.java)
            startActivity(intent)
            finish()
        }

    }


}

버튼을 클릭했을 때 인텐트를 이용해 화면을 전환시키는 것 빼고는 전에 사용한 livedatabinding과 방법이 같다.

버튼을 xml에서 처리할 수 있는데 코드상에서 처리한 이유는 xml에서 처리하기 불편해서 이다.

저 버튼은 최댓값을 바꾸는 화면으로 전환해 준다.

이제 SetMaxActivity를 보자.

class SetMaxActivity : AppCompatActivity() {
    private lateinit var mbind : ActivitySetnumBinding

    private val model : MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mbind = DataBindingUtil.setContentView(this,R.layout.activity_setnum)

        mbind.lifecycleOwner = this
        mbind.viewmodelSetMaxNum = MainViewModel()

        var max : EditText = findViewById(R.id.maxnum)
        var completeBtn : Button = findViewById(R.id.complete)

        completeBtn.setOnClickListener{
            model.setMaxNum(Integer.parseInt(max.text.toString()))
            var intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            finish()
        }
    }
}

 

최대 숫자를 입력하고 버튼을 누를 시 MainViewModel에 있는 setMaxNum을 통해 최대 숫자를 정해준다.

 

그럼 xml로 넘어가자

먼저 activity_main이다.

<?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"
    tools:context=".view.MainActivity">


    <data>
        <variable
            name="viewModel"
            type="com.example.pick_up_game.viewModel.MainViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="숫자 최대치 정하기"
            android:layout_gravity="end"
            android:id="@+id/setMaxNumbtn"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="기본 최대치 : 100"
            android:layout_gravity="center"
            android:gravity="center"
            android:textSize="20dp"
            />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="321dp"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="@{viewModel.text}"
            android:textSize="60dp" />

        <Button
            android:layout_width="130dp"
            android:layout_height="100dp"
            android:layout_marginTop="10dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/pick_up"
            android:onClick="@{() -> viewModel.getNum()}"
            android:text="번호 뽑기"
            android:textSize="20dp"
            android:textStyle="bold"
            />

        <Button
            android:layout_width="130dp"
            android:layout_height="100dp"
            android:layout_marginTop="10dp"
            android:layout_gravity="center"
            android:text="뽑은 번호 보기"
            android:textStyle="bold"
            android:id="@+id/allNum"
            android:onClick="@{() -> viewModel.showAllNum()}"
            />



    </LinearLayout>



</layout>

참고로 버튼이 3개가 있는데 1나만 코드로 처리하고 나머지 2개는 xml에서 처리했다.

그다음 activity_setnum을 보자.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    >

    <data>
        <variable
            name="viewmodelSetMaxNum"
            type="com.example.pick_up_game.viewModel.MainViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="최대값을 적어 주십시오"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginTop="300dp"
        android:id="@+id/maxnum"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="완료"
        android:textSize="20dp"
        android:id="@+id/complete"
        android:layout_gravity="center"/>

    </LinearLayout>
</layout>

이렇게 번호 뽑기 앱을 만들어 보았다.

한번 만들어 보니, MVVM을 어떻게 써야 할지 감이 잡히더라.

간단한 거라도 좋으니 일단 응용해서 만들어 보는 것을 추천한다.

 

전체 코드는 깃허브에서 볼 수 있다.

https://github.com/krapoi/Pick_Up_App

 

GitHub - krapoi/Pick_Up_App: Use MVVM patten

Use MVVM patten. Contribute to krapoi/Pick_Up_App development by creating an account on GitHub.

github.com

 

반응형