1) 입력값 받아오기 (AddTextChangedListener)
문자열이 변경되면 알려주는 리스너인 AddTextChangedListener 를 불러오자.
// 문자열이 변경되면 알려주는 리스너
inputEditText.addTextChangedListener { text ->
inputNumber = text.toString().toInt()
Log.d("inputNumber", inputNumber.toString())
}
text.toString().toInt()
String 을 Int 로 변경하는 코드에서 오류 발생.
1-1) 예외처리 ( int 의 범위 )
try ~ catch 문을 사용할 수도 있지만
EditText 의 속성인 maxLength 를 지정해주도록 하자.
int 의 범위는 대락 2억 (10자리 수) 까지 이지만
맨 앞자리 수가 2보다 큰 수, 예를 들어 9가 된다면 오류가 발생하므로
9자리 숫자까지로 제한해주자.
activity_main.xml
<EditText
...
android:maxLength="9"
1-2) 예외처리 ( 빈 문자열 )
빈 문자열을 toString().toInt() 로 변환하는 데 오류가 발생한다.
따라서 아래와 같이, 입력값이 “빈 문자열” 인경우에 대한 예외처리를 해주자.
inputEditText.addTextChangedListener { text ->
inputNumber = if(text.isNullOrEmpty()) {
0
} else {
text.toString().toInt()
}
...
}
2) 변환 기능 구현
2-1) 숫자 변환
cm 를 m 로 변환하는 기능을 구현해보자.
// 문자열이 변경되면 알려주는 리스너
inputEditText.addTextChangedListener { text ->
// cm -> m
var outputNumber = inputNumber.times(0.01)
if(cmToM) {
outputTextView.text = inputNumber.times(0.01).toString()
}else{
outputTextView.text = inputNumber.times(100).toString()
}
}
swap 이미지버튼을 누르면 단위가 변경된다.
이때, m를 cm 로 변경하는데 EditText 의 maxLength 가 9였으므로
100을 곱한 cm 변환 결과는 11자리 수가 된다.
이는 정수 범위를 벗어난 것이므로
간단히 maxLength 를 7로 수정해준다.
2-2) 단위 텍스트 swap
이제 swap 버튼을 눌렀을 때
inputUnitTextView 와 outputTextView 의 text 를 변경해보자.
swap 이미지 버튼을 누르면
cm 를 m 로, m 를 cm 로 변경한다.
var cmToM = true
swapImageButton.setOnClickListener {
cmToM = cmToM.not() // !cmToM
if (cmToM) {
inputUnitTextView.text = "cm"
outputUnitTextView.text = "m"
outputTextView.text = inputNumber.times(0.01).toString()
} else {
inputUnitTextView.text = "m"
outputUnitTextView.text = "cm"
outputTextView.text = inputNumber.times(100).toString()
}
}
3) 전체 코드
MainActivity.kt
package com.part1.chapter3
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.core.widget.addTextChangedListener
import com.part1.chapter3.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
// 바인딩 변수 선언
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// binding 변수에 instance 할당
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
// id 값은 유일하지 않다.
// activity_main 이 아닌 다른 xml 파일에서도
// outputTextView 를 id 로 하는 뷰를 생성할 수 있다.
// 따라서 id 가 중복이 되는 이슈
val outputTextView = binding.outputTextView
val outputUnitTextView = binding.outputUnitTextView
val inputEditText = binding.inputEditText
val inputUnitTextView = binding.inputUnitTextView
val swapImageButton = binding.swapImageButton
var inputNumber : Int = 0
var cmToM = true
// 문자열이 변경되면 알려주는 리스너
inputEditText.addTextChangedListener { text ->
inputNumber = if(text.isNullOrEmpty()) {
0
} else {
text.toString().toInt()
}
// cm -> m
var outputNumber = inputNumber.times(0.01)
if(cmToM) {
outputTextView.text = inputNumber.times(0.01).toString()
}else{
outputTextView.text = inputNumber.times(100).toString()
}
}
swapImageButton.setOnClickListener {
cmToM = cmToM.not() // !cmToM
if (cmToM) {
inputUnitTextView.text = "cm"
outputUnitTextView.text = "m"
outputTextView.text = inputNumber.times(0.01).toString()
} else {
inputUnitTextView.text = "m"
outputUnitTextView.text = "cm"
outputTextView.text = inputNumber.times(100).toString()
}
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<!-- 값 입력받는 EditText -->
<EditText
android:id="@+id/inputEditText"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:hint="자연수를 입력해주세요"
android:maxLength="7"
android:textColorHint="@color/purple_200"
android:textSize="30sp"
android:textColor="@color/purple_500"
android:textStyle="italic"
android:gravity="end"
android:inputType="number"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.4"
app:layout_constraintHorizontal_bias="0.1"
/>
<!-- 입력받은 값을 처리하여 화면에 보여주는 TextView -->
<!-- inputEditText 오른쪽의 단위 표시할 TextView -->
<TextView
android:id="@+id/outputTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:gravity="end"
android:text="100"
android:textColor="@color/black"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="@+id/inputEditText"
app:layout_constraintStart_toStartOf="@+id/inputEditText"
app:layout_constraintTop_toBottomOf="@id/inputEditText" />
<TextView
android:id="@+id/inputUnitTextView"
android:text="cm"
android:textSize="20sp"
android:layout_marginStart="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/inputEditText"
app:layout_constraintTop_toTopOf="@id/inputEditText"
app:layout_constraintBaseline_toBaselineOf="@id/inputEditText"
/>
<!-- outputTextView 오른쪽의 단위 표시할 TextView -->
<TextView
android:id="@+id/outputUnitTextView"
android:text="m"
app:layout_constraintStart_toEndOf="@id/outputTextView"
app:layout_constraintBaseline_toBaselineOf="@id/outputTextView"
android:textSize="20sp"
android:layout_marginStart="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="@+id/swapImageButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="8dp"
android:src="@drawable/ic_baseline_swap_vert_24"
app:layout_constraintBottom_toBottomOf="@id/outputTextView"
app:layout_constraintStart_toEndOf="@id/inputUnitTextView"
app:layout_constraintTop_toTopOf="@id/inputEditText" />
</androidx.constraintlayout.widget.ConstraintLayout>
'안드로이드 앱(Kotlin|Java) > [2025~] 안드로이드 앱' 카테고리의 다른 글
Part1_Ch03_07 복습 및 한걸음 더 (0) | 2025.04.09 |
---|---|
Part1_Ch03_06 화면전환 시 데이터 유지 (0) | 2025.04.09 |
Part1_Ch03_04 UI 요소 가져오기 (0) | 2025.04.09 |
Part1_Ch03_03 길이변환 UI 그리기 (2) (0) | 2025.04.09 |
Part1_Ch03_02 길이변환 UI 그리기 (1) (2) | 2025.02.04 |