전체 코드 : https://github.com/ryr0121/AndroidPractice/tree/main/unitConversionApp
구현 결과
주요 기능
- cm <-> m 간의 값 변환 (초기 상태 : cm단위의 값 입력 시, m의 값으로 변환)
- 버튼을 통한 변환 단위 교체
ConstraintLayout으로 view 배치
ConstraintLayout은 상대적 제약조건을 통해 배치가 이루어지므로 렌더링 속도 향상 등의 이점 존재
<?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">
...
</androidx.constraintlayout.widget.ConstraintLayout>
구현을 위해 사용한 컴포넌트는 아래와 같음
각 컴포넌트들에 대해 layout_..._...의 속성값 지정을 통해 상대적인 제약조건을 추가하여 UI 배치 진행
- EditText : 변환시킬 정수값을 입력받기 위한 컴포넌트
- hint : 입력값에 대한 정보를 나타내는 텍스트
- maxLength : 입력값의 최대 길이 지정
- inputType : 입력값의 타입 지정 (number : 정수 / numberDecimal : 소수를 포함한 숫자)
<EditText
android:id="@+id/inputEditText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="end"
android:hint="자연수를 입력해주세요"
android:inputType="numberDecimal"
android:maxLength="7"
android:textColorHint="@color/purple"
android:textSize="20sp"
android:textStyle="italic"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4"
app:layout_constraintHorizontal_bias="0.2" />
- TextView : 단위가 변환된 값 / 입,출력 값의 단위 표시를 위한 컴포넌트
<TextView
android:id="@+id/outputTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="end"
android:text="0"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="@+id/inputEditText"
app:layout_constraintStart_toStartOf="@id/inputEditText"
app:layout_constraintTop_toBottomOf="@id/inputEditText" />
<TextView
android:id="@+id/inputUnitTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="cm"
android:textSize="20sp"
android:layout_marginStart="16dp"
app:layout_constraintStart_toEndOf="@+id/inputEditText"
app:layout_constraintBaseline_toBaselineOf="@id/inputEditText" />
<TextView
android:id="@+id/outputUnitTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="m"
android:textSize="20sp"
android:layout_marginStart="16dp"
app:layout_constraintStart_toEndOf="@+id/outputTextView"
app:layout_constraintBaseline_toBaselineOf="@id/outputTextView" />
- ImageButton : 단위 교체를 위한 컴포넌트
- src 속성값 지정을 통해 버튼에 사용할 이미지 선택
<ImageButton
android:id="@+id/swapImgButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/baseline_swap_vert_24"
app:layout_constraintStart_toEndOf="@id/inputUnitTextView"
app:layout_constraintTop_toTopOf="@id/inputEditText"
app:layout_constraintBottom_toBottomOf="@id/outputTextView"
android:layout_marginStart="16dp" />
MainActivity 내에서 ViewBinding을 통해 findById 메소드 사용의 단점을 보완
(예. 중복된 ID 값으로 인한 문제, ID값 분실, 지정된 xml에서의 뷰 포함 여부 확인 어려움 등)
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
val outputTextView = binding.outputTextView
val outputUnitTextView = binding.outputUnitTextView
val inputEditText = binding.inputEditText
val inputUnitTextView = binding.inputUnitTextView
val swapImgButton = binding.swapImgButton
...
}
...
}
EditText의 addTextChangedListener 메소드를 통해 입력값의 변화가 감지될 때마다 관련된 이벤트 처리 가능
inputEditText.addTextChangedListener { text ->
inputNumber = if (text.isNullOrEmpty()) { 0 } else { text.toString().toInt() }
if (cmToM) {
outputTextView.text = inputNumber.times(0.01).toString()
} else {
outputTextView.text = inputNumber.times(100).toString()
}
}
onSaveInstanceState 메소드와 onRestoreInstanceState 메소드를 통해, 단위 변환 상태에 대한 '임시 UI 상태 저장 및 복원' 가능
(공식 문서 : https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ko)
override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
outState.putBoolean("cmToM", cmToM)
super.onSaveInstanceState(outState, outPersistentState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
cmToM = savedInstanceState.getBoolean("cmToM")
binding.inputUnitTextView.text = if(cmToM) "cm" else "m"
binding.outputUnitTextView.text = if(cmToM) "m" else "cm"
super.onRestoreInstanceState(savedInstanceState)
}
'Android' 카테고리의 다른 글
[Android] "스톱워치 앱" 구현 (0) | 2024.07.02 |
---|---|
[Android] "계산기 앱" 구현 (0) | 2024.06.30 |
[Android] "응급 의료정보 앱" 구현 (0) | 2024.06.30 |
[Android] "숫자세기 앱" 구현 (7) | 2024.06.25 |