전체 코드 : 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

+ Recent posts