TIL/selfpractice

mvvm 패턴 계산기

crablo 2024. 3. 20. 14:29
728x90

mvvm 패턴을 이용해서 간단한 계산기를 만들어보았다.

mvvm 개념이 중요해서

https://velog.io/@kyeun95/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-MVVM-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80

 

[디자인 패턴] MVVM 패턴이란?

개념 :MVVM (Model-View-ViewModel) 패턴은 Model View, View, Model의 약자로 프로그램의 비지니스 로직과, 프레젠테이션 로직을 UI로 명확하게 분리하는 패턴입니다.데이터를 다루는 부분. 비즈니스 로직을

velog.io

해당 블로그를 보고 이해했다.

mvvm은 기본적으로 내 코드를 분리된 모듈로 관리한다고 보면 되는데

MODEL(data)

VIEWMODEL(logic)

VIEW(UI)

이렇게 정리해보았다.

VIEW가 UI를 담당하고 MODEL은 데이터를 관리한다면

VIEW와 MODEL은 직접적으로 작용하지 않고

VIEWMODEL을 통해서 데이터를 주고 받는다고 정리해볼 수 있을것 같다.

먼저내가 프로젝트에서 화면을 먼저 작성했다.

[activity_main.xml] 파일

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".view.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="150dp"
        android:orientation="vertical">
        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="30dp"
            app:cardCornerRadius="8dp"
            app:cardElevation="8dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/addSymbol"
                android:textColor="@color/red"
                android:layout_gravity="center"
                android:textSize="30sp"
                android:text="+"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_weight="1"
                    android:padding="16dp">
                    <EditText
                        android:layout_width="match_parent"
                        android:layout_height="80dp"
                        android:id="@+id/editTextNum1"
                        android:textSize="26sp"
                        android:hint = "0"
                        android:layout_marginEnd="6dp"
                        android:textAlignment="center"
                        android:textColor="@color/black"/>

                </LinearLayout>
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_weight="1"
                    android:padding="16dp">
                    <EditText
                        android:layout_width="match_parent"
                        android:layout_height="80dp"
                        android:id="@+id/editTextNum2"
                        android:textSize="26sp"
                        android:hint="0"
                        android:layout_marginStart="6dp"
                        android:textAlignment="center"
                        android:textColor="@color/black"/>

                </LinearLayout>
            </LinearLayout>
            
        </androidx.cardview.widget.CardView>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/calculateButton"
            android:text="CALCULATE"
            android:layout_marginStart="25dp"
            android:layout_marginEnd="25dp"
            android:backgroundTint="@color/red"
            android:layout_gravity="center"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/resultTitle"
            android:layout_gravity="center"
            android:textSize="30sp"
            android:layout_marginTop="12dp"
            android:textColor="@color/black"
            android:text="RESULT"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/resultTextView"
            android:layout_gravity="center"
            android:textSize="120sp"
            android:textColor="@color/red"
            android:text="0"/>
    </LinearLayout>
</LinearLayout>

activity_main.xml

그 후 파일 디렉토리를 아래와 같이 만들었다.

파일은 model view viewmodel로 3개의 파일을 만들었다.

model은 데이터를 담고 있는 파일
view는 화면에요소를 메모리에 올리는 ui와 관련된 파일
viewmodel은 model 과 view사이의 데이터가 오고가는 로직을 담당하는 파일

먼저, 데이터를 담당하는 model 파일을 간단하게 data class로 db연결없이 만들었다.

코드는 아래와 같다.

[CalculatorData.kt]

package com.ellycrab.learnmvvm.model

data class CalculatorData(val num1:Int, val num2:Int, val sum:Int)

 

그 후 로직을 담당하는 viewmodel 파일 CalculatorViewModel.kt 파일을 작성했다.

[CalculatorViewModel.kt]

package com.ellycrab.learnmvvm.viewmodel

import androidx.lifecycle.ViewModel
import com.ellycrab.learnmvvm.model.CalculatorData

class CalculatorViewModel:ViewModel() {
    fun calculateSum(num1:Int, num2:Int):CalculatorData{
        val sum = num1+num2
        return CalculatorData(num1,num2, sum)
    }
}

마지막으로 ui 를 담당하는 MainActivity.kt 파일을 작성했다.

package com.ellycrab.learnmvvm.view

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.ellycrab.learnmvvm.databinding.ActivityMainBinding
import com.ellycrab.learnmvvm.viewmodel.CalculatorViewModel


class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var calculatorViewModel: CalculatorViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //viewmodelprovide는 뷰모델클래스의 인스턴스를 획득할 수 있게한다.
        //this =>owner =>means main activity itself
        //초기화
        calculatorViewModel = ViewModelProvider(this).get(CalculatorViewModel::class.java)

        binding.calculateButton.setOnClickListener {
            val num1 = binding.editTextNum1.text.toString().toIntOrNull() ?: 0
            val num2 = binding.editTextNum2.text.toString().toIntOrNull() ?: 0

            val result = calculatorViewModel.calculateSum(num1,num2)

            binding.resultTextView.text = "${result.sum}"
        }

    }
}

그래서 결과는 아래와 같이 나온다.

728x90

'TIL > selfpractice' 카테고리의 다른 글

3월5일 스파르타 코딩클럽 lv1과제 및 깃허브 업로드  (0) 2024.03.05
깃허브 좌충우돌기  (0) 2024.02.28
스코프 함수  (1) 2024.01.19
지연 초기화  (1) 2024.01.17
null safety  (1) 2024.01.17