내가 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
'안드로이드' 카테고리의 다른 글
[안드로이드] 인텐트필터 알아보기 (0) | 2022.04.29 |
---|---|
[안드로이드] 인텐트 알아보기 (0) | 2022.04.28 |
[안드로이드] 라이브 데이터 + 데이터 바인딩 알아보기(LiveData + DataBinding) (0) | 2022.03.11 |
[안드로이드] Databinding 알아보기 (0) | 2022.03.09 |
[안드로이드/JAVA] 안드로이드로 Wordle 만들어 보기 #2 (0) | 2022.03.08 |