이 글은 유데미 강의 Android 12 및 Kotlin 개발 완전 정복을 참고하여 작성하였습니다.
작성자 : 조성현
개발환경은 mac, Android Studio입니다.
강의 영상 96(onDecimalPoint) ~ 100(챕터 요약) 의 관한 리뷰 형식의 글입니다.
이전 시간 까지 배웠던것들입니다.
- 1. Constrain_Layout 이 아닌 LinearLayout 을 이용하여 ui 를 만든다.
- 2. 버튼을 누르는 이벤트에 onClick Listner 가 아닌 메서드를 연결 하여 값을 넘기는 것을 배웠습니다.
이번 강의 96~100 은 flag 개념을 이용한 사실상 문자열 다루기를 주로 다룹니다.
이번 강의에서 나오는 계산기 기능 요구 사항 입니다.
1. 소수점 추가 기능
2. 숫자 계산 기능
1. 수수점 계산
Main.kt file 에 소수점 (Decimal_Point)에 관한 메서드(onDecimalPoint)를 생성하고 UI와 연결해 줍니다.
activity_main.xml
<Button
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:id="@+id/btnDecimal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="onDecimalPoint"
android:text="." />
click 을 하면 onDecimalPoint 메서드를 호출 하게 합니다.
android:onClick="onDecimalPoint"
계산기에서 소수점기능의 중요한 부분은 "1.2.1.2" 와 같은 숫자는 없다 + 마지막은 숫자로 끝난다 입니다.
->마지막으로 숫자로 끝나는 특성은 계산기능에도 이용합니다.
현제 계산할 숫자의 상태를 받고 상태를 변환해 주는 함수를 작성하고 이를 "Flag" 라고 도 부른다고 합니다.
간단하게 lastNumeric 과 lastDot 이라는 변수를 추가하여 현제의 값의 상태를 나타내줍니다.
여담 .refacoting 할때 class 로 빼면 좋을 듯 보입니다.
class MainActivity : AppCompatActivity() {
var lastNumeric: Boolean = false
var lastDot: Boolean = false
//lastDot 이 true 이면 점을 더 이상 추가 못하게 합니다.
//lastNumeric 이 true 이면 값이 마지막으로 끝나는 것을 나타냅니다
private var tvInput:TextView?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tvInput = findViewById(R.id.tvInput)
}
fun onDigit(view: View){
tvInput?.append((view as Button).text)
lastNumeric = true
}
fun onClear(view: View){
tvInput?.text = ""
lastNumeric = false
lastDot = false
}
fun onDecimalPoint(view: View)
{
// 마지막이 숫자인 경우 & 앞에 점이 없을때 점을 추가합니다.
if (lastNumeric && !lastDot) {
tvInput?.append(".")
lastNumeric = false // Update the status(flag)
lastDot = true // Update the flag
}
}
2. 숫자 계산 기능
숫자를 계산 하는 기능에는 연산자를 확인하고 계산을 진행합니다.
2.1 연산자 확인에 관한 요구 사항
- 2.1.1 다음 예들은 연산이 불가능합니다.
ex)
1. 숫자로 끝나지 않은 경우 : 9*
2. 공백
- 2.1.2 음의 정수는 계산이 가능해야합니다.
ex) -1 * -2
- 2.1.3 연산자가 두개이상 오는 경우
ex) 1+2+3
contains 와 startWith 라는 String class 의 함수를 이용하여 연산자 추가여부를 먼저 파악 합니다. 요구 사항 (2.1.2)
private fun isOperatorAdded(value: String): Boolean {
return if (value.startsWith("-")) {
false
} else {
(value.contains("/")
|| value.contains("*")
|| value.contains("-")
|| value.contains("+"))
}
}
}
onOperator 함수를 통해 연산자의 추가 여부를 결정합니다. 요구 사항 (2.1.1,2.1.3)
fun onOperator(view: View) {
tvInput?.text?.let {
if (lastNumeric && !isOperatorAdded(it.toString())) {
tvInput?.append((view as Button).text)
lastNumeric = false // Update the flag
lastDot = false // Reset the DOT flag
}
}
}
it.toSting() 에서 it 는 람다 함수 let 의 대상을 받습니다. 추가적인 문법 설명은 생략 하겠습니다.
2.2 연산의 관한 요구사항
2.2.1 onEqual 함수를 만들고 연산 기능을 완성합니다.
1 . = 는 마지막 한번 만 사용합니다.
2 . 연산의 결과에 대한 예외 처리를 해줍니다. 0으로 나누기 (무한대)
2.2.2 계산 결과는 정수로 표현합니다.
float 를 계산 하면 1.0 과 같은 계산의 결과가 나오는데 1 로 바꿔 주는 함수를 만들어 줍니다.
String class 의 substring 메서드를 이용하여 문자열 슬라이싱을 해줍니다. - 요구사항 2.2.2
private fun removeZeroAfterDot(result: String): String {
var value = result
if (result.contains(".0")) {
value = result.substring(0, result.length - 2)
}
return value
}
연산의 예외처리는 다음 같이 ArithmeticException 을 걸어 줍니다. 요구 사항 2.2.1
try{
} catch (e: ArithmeticException) {
e.printStackTrace()
}
}
결과 코드
fun onEqual(view: View) {
// If the last input is a number only, solution can be found.
if (lastNumeric) {
// Read the textView value
var tvValue = tvInput?.text.toString()
var prefix = ""
try {
// Here if the value starts with '-' then we will separate it and perform the calculation with value.
if (tvValue.startsWith("-")) {
prefix = "-"
tvValue = tvValue.substring(1);
}
// If the inputValue contains the Division operator
when {
tvValue.contains("/") -> {
// Will split the inputValue using Division operator
val splitedValue = tvValue.split("/")
var one = splitedValue[0] // Value One
val two = splitedValue[1] // Value Two
if (prefix.isNotEmpty()) { // If the prefix is not empty then we will append it with first value i.e one.
one = prefix + one
}
/*Here as the value one and two will be calculated based on the operator and
if the result contains the zero after decimal point will remove it.
And display the result to TextView*/
tvInput?.text = removeZeroAfterDot((one.toDouble() / two.toDouble()).toString())
}
tvValue.contains("*") -> {
// If the inputValue contains the Multiplication operator
// Will split the inputValue using Multiplication operator
val splitedValue = tvValue.split("*")
var one = splitedValue[0] // Value One
val two = splitedValue[1] // Value Two
if (prefix.isNotEmpty()) { // If the prefix is not empty then we will append it with first value i.e one.
one = prefix + one
}
/** Here as the value one and two will be calculated based on the operator and
if the result contains the zero after decimal point will remove it.
And display the result to TextView
*/
tvInput?.text = removeZeroAfterDot((one.toDouble() * two.toDouble()).toString())
}
tvValue.contains("-") -> {
// If the inputValue contains the Subtraction operator
// Will split the inputValue using Subtraction operator
val splitedValue = tvValue.split("-")
var one = splitedValue[0] // Value One
val two = splitedValue[1] // Value Two
if (prefix.isNotEmpty()) { // If the prefix is not empty then we will append it with first value i.e one.
one = prefix + one
}
/** Here as the value one and two will be calculated based on the operator and
if the result contains the zero after decimal point will remove it.
And display the result to TextView
*/
tvInput?.text = removeZeroAfterDot((one.toDouble() - two.toDouble()).toString())
}
tvValue.contains("+") -> {
// If the inputValue contains the Addition operator
// Will split the inputValue using Addition operator
val splitedValue = tvValue.split("+")
var one = splitedValue[0] // Value One
val two = splitedValue[1] // Value Two
if (prefix.isNotEmpty()) { // If the prefix is not empty then we will append it with first value i.e one.
one = prefix + one
}
/**Here as the value one and two will be calculated based on the operator and
if the result contains the zero after decimal point will remove it.
And display the result to TextView
*/
tvInput?.text = removeZeroAfterDot((one.toDouble() + two.toDouble()).toString())
}
}
} catch (e: ArithmeticException) {
e.printStackTrace()
}
}
}
'GDSC HUFS 4기 > Kotlin Team #7' 카테고리의 다른 글
[7팀] 퀴즈 앱 안드로이드 12 part 2 (0) | 2022.11.07 |
---|---|
[7팀] 퀴즈 앱 안드로이드 12 part 1 (0) | 2022.11.07 |
[7팀] 계산기 - XML 사용법과 UI 생성법 배우기 - 안드로이드12 (0) | 2022.10.31 |
[7팀]코틀린 기초 더 배우기(2) (0) | 2022.10.11 |
[7팀]코틀린 기초 더 배우기(1) (0) | 2022.10.10 |