본문 바로가기

대외활동

[Android] Kotlin - 사칙연산 계산기 만들기 / 예외 처리 / 함수 구조화


결과

수정 전
수정 후

 

 

 

 


과정

 

1. 숫자 2개를 각각 입력한다.

2. 연산자를 선택한다.

3. 결과 계산 버튼을 클릭한다.

4. 결과가 출력된다.

 

 

 

 


처음 코드

MainActivity.kt

package kr.co.lion.ex04

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kr.co.lion.ex04.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding : ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)

activityMainBinding.apply {
buttonResult.setOnClickListener {
// 숫자1
var num1 = editTextText.text.toString().toDouble()
// 숫자2
var num2 = editTextText2.text.toString().toDouble()
// 연산 결과
var result:Double


when(toggleGroup.checkedButtonId) {
// 덧셈 선택한 경우
R.id.buttonPlus -> {result = num1 + num2
textViewResult.text = "결과는 ${result}입니다."}
// 뻴셈 선택한 경우
R.id.buttonMinus -> {result = num1 - num2
textViewResult.text = "결과는 ${result}입니다."}
// 곱셈 선택한 경우
R.id.buttonMulti -> {result = num1 * num2
textViewResult.text = "결과는 ${result}입니다."}
// 나눗셈 선택한 경우
R.id.buttonDivide -> {result = num1 / num2
textViewResult.text = "결과는 ${result}입니다."}
// 선택하지 않은 경우
else -> textViewResult.text = "연산자를 선택하시오."
}
}
}

}
}

 

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"
android:padding="20dp"
tools:context=".MainActivity" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="숫자1"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />

<EditText
android:id="@+id/editTextText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="text" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="숫자2"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />

<EditText
android:id="@+id/editTextText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="text" />

</LinearLayout>

<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/toggleGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
app:singleSelection="true">

<Button
android:id="@+id/buttonPlus"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+" />

<Button
android:id="@+id/buttonMinus"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-" />

<Button
android:id="@+id/buttonMulti"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="*" />

<Button
android:id="@+id/buttonDivide"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="/" />
</com.google.android.material.button.MaterialButtonToggleGroup>

<Button
android:id="@+id/buttonResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="결과 계산" />

<TextView
android:id="@+id/textViewResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="결과"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>

  

 

 

 

 


보완한 점 & 코드

 

1. 예외 처리

- 숫자를 하나라도 입력하지  않고 결과 계산 버튼을 누른 경우

- 연산자를 선택하지 않고 결과 계산 버튼을 누른 경우

 

2. 입력하는 editText에 숫자만 넣을 수 있게 지정

 

3. 함수 생성 후 구조화

- 예외처리 함수

- 변수 초기화 함수

- 에러 메세지 출력 함수

 

4. 디자인 수정

- material3의 자료를 이용해 버튼에 아이콘 추가

- 그림자, 색상 변경

 

 

MainActivity.kt

package kr.co.lion.ex04_retry

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.view.isVisible
import kr.co.lion.ex04_retry.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

lateinit var activityMainBinding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)

// 예외 처리 및 변수 초기화 함수 호출
handleUserInput()
}

// 예외 처리 함수
fun handleUserInput() {
activityMainBinding.apply {
resultBtn.setOnClickListener {
// 숫자 입력 여부 확인
if (editTextNum1.text.isEmpty() || editTextNum2.text.isEmpty()) {
showErrorMessage("숫자를 입력하시오!")
return@setOnClickListener
}

// 연산자 선택 여부 확인
if (toggleGroup.checkedButtonId == -1) {
showErrorMessage("연산자를 선택하시오!")
return@setOnClickListener
}

// 변수 초기화 함수 호출
calculateResult()
}
}
}

// 변수 초기화 함수
fun calculateResult() {
activityMainBinding.apply {
// 에러 해결
textExcep.isVisible = false

// 입력 받는 숫자
val num1 = editTextNum1.text.toString().toDouble()
val num2 = editTextNum2.text.toString().toDouble()

// 결과 계산
var result = 0.0

when (toggleGroup.checkedButtonId) {
R.id.buttonPlus -> result = num1 + num2
R.id.buttonMinus -> result = num1 - num2
R.id.buttonMulti -> result = num1 * num2
R.id.buttonDiv -> result = num1 / num2
}

// 결과 출력
textResult.text = "result: $result"
}
}

// 에러 메시지 출력 함수
fun showErrorMessage(message:String){
activityMainBinding.apply {
textExcep.isVisible = true
textExcep.text = message
}
}
}

 

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"
android:padding="20dp"
tools:context=".MainActivity">

<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:text="Calculator"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="num1"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="#858585" />

<EditText
android:id="@+id/editTextNum1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:ems="10"
android:inputType="number" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="num2"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="#858585" />

<EditText
android:id="@+id/editTextNum2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
android:ems="10"
android:inputType="number" />

</LinearLayout>
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/toggleGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
app:singleSelection="true">

<Button
android:id="@+id/buttonPlus"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+"
android:textColor="#92C3DA"
android:textSize="20sp"
app:strokeColor="#92C3DA" />

<Button
android:id="@+id/buttonMinus"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-"
android:textColor="#92C3DA"
android:textSize="20sp"
app:strokeColor="#92C3DA" />

<Button
android:id="@+id/buttonMulti"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="*"
android:textColor="#92C3DA"
android:textSize="20sp"
app:strokeColor="#92C3DA" />

<Button
android:id="@+id/buttonDiv"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="/"
android:textColor="#92C3DA"
android:textSize="20sp"
app:strokeColor="#92C3DA" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:orientation="vertical">

<Button
android:id="@+id/resultBtn"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="148dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:backgroundTint="#F4F8FF"
android:elevation="3dp"
android:text="result"
android:textColor="#03A9F4"
android:textSize="16sp"
app:icon="@drawable/library_books"
app:iconGravity="textStart"
app:iconPadding="4dp"
app:iconTint="#03A9F4"
app:rippleColor="@color/black"
app:strokeColor="@color/black" />

<TextView
android:id="@+id/textExcep"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="#E91E63"
android:textSize="14sp"
android:textStyle="italic"
android:visibility="invisible" />

<TextView
android:id="@+id/textResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:text="result:"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="#6E6E6E" />

</LinearLayout>

</LinearLayout>

 

 

 

 


알게된 점

 

1. 함수를 이용한 구조화

- 함수를 여러 개 만든다고 모두 main에서만 호출하는 게 아니다. (흐름에 맞게 함수에서 함수 호출 가능)

- 역할에 맞는 함수를 만들자. (에러 메세지 출력 함수처럼)

 

2. 버튼 디자인

- style에서 @style/Widget.Material3.Button.IconButton를 선택하고 icon 속성에 그림 넣을 수 있다.

- elevation 속성으로 그림자 효과 가능!

    -> but 버튼 스타일에 따라 적용 안될 수 있음.

 

3. 예외 처리의 중요성

- 사용자에게 필요한 정보를 알리기 위해 예외 처리하는 연습을 하자

- isEmpty(): 값이 비었나?

- isVisible(): 보이게 할 건가?

- 버튼 아이디가 -1이면 선택되지 않은 것!

- return@메서드명: 메서드 종료

- 에러 메세지 출력 함수에서는 버튼 클릭 시로 설정 안해도 됨

    -> why? 이미 버튼 클릭 시 함수 안에서 호출함

- 에러 해결 후 변화에 대한 대응도 필요

 

 

출처: 멋쟁이 사자처럼 앱스쿨 2기에서 공부 중~