TIL) 0905

Hanseul Lee·2022년 9월 5일
0

TIL

목록 보기
5/23

simpleDateFormat

날짜 형식을 지정(날짜 → 텍스트)하고 파싱(텍스트 → 날짜)하는 클래스다.

SimpleDateFormat("E MMM d", Locale.getDefault())
  • “E MMM d”와 같은 패턴 문자열은 날짜 및 시간 형식의 표현이다. 2018년 1월 4일이면 “Wed, Jul 4”와 같이 된다.
    • E → 요일
    • d → 일
    • M → 월
    • y → 연도
  • Locale 객체는 특정한 지리적, 정치적, 문화적 지역을 나타낸다. 지역의 규칙에 맞게 숫자나 날짜와 같은 정보 표시를 병경하는 데 사용한다. 날짜와 시간은 세계 각지에서 서로 다르게 작성되기 때문에 언어에 매우 민감하다. 때문에 Locale.getDefault()로 사용자의 기기에 설정된 언어 정보를 가져와 SimpleDateFormat 생성자에 전달해야 한다.

elvis 연산자

?:의 형태로 왼쪽 표현식이 null이 아닐 때 이 값을 사용한다는 것을 의미한다. null 체크를 간단하게 수행하는 연산자다. 왼쪽 피연산자가 null이 아니면 그 값을 반환하고, null이면 오른쪽 피연산자를 반환한다.

_price.value = (quantity.value ?: 0) * PRICE_PER_CUPCAKE

위 코드는 quantity.value가 null이면 0을, 아니면 해당 값을 그대로 사용한다는 뜻!

cf) 이 연산자는 엘비스 프레슬리의 이름을 땄다. 옆에서 보면 앞머리를 높이 세운 엘비스 프레슬리 같으니까!

DataBinding 사용 시 String.xml을 통해 값 출력하기 (DataBinding 레이아웃 표현식)

문자열 resouce를 사용하고 ViewModel에서 매개변수를 전달하는 방법은 다음 예시처럼 하면 된다.

// fragment_flavor.xml

<TextView
                android:id="@+id/subtotal"
                ...
                android:text="@{@string/subtotal_price(viewModel.price)}"
                tools:text="Subtotal $5.00" />
// string.xml

<resources>
    ...
    <string name="subtotal_price">Subtotal %s</string>
    ...
</resources>

LiveData 변환 메서드

LiveData 소스에서 데이터 조작을 실행하고 결과 LiveData 객체를 반환한다. 쉽게 말해 LiveData 값을 다른 값으로 변환한다. Observer가 객체를 관찰하고 있지 않으면 변환은 일어나지 않는다는 걸 유의하자.

Transformations.map()이 변환 메서드 중 하나다.

LiveData 변환을 사용할 수 있는 예는 다음과 같이 있다.

  • 표시할 날짜 및 시간 문자열 형식 지정
  • 항목 목록 정렬
  • 항목 필터링 또는 그룹화
  • 모든 항목 합계, 항목 수, 마지막 항목 반환 등 → 목록의 결과 계산
private val _price = MutableLiveData<Double>()
val price: LiveData<String>

위와 같이 Double에서 String으로 변경하려면 다음처럼 한다.

private val _price = MutableLiveData<Double>()
val price: LiveData<String> = Transformations.map(_price) {
   NumberFormat.getCurrencyInstance().format(it)
}
  • Transformations.map()으로 새로운 변수를 초기화하고 _price와 람다 함수를 전달한다.
  • NumberFormat 클래스의 getCurrencyInstance는 현지 통화 형식으로 변경하는 메서드다.

popUpTo VS popUpToInclusive

NavGraph에서 대상 간 이동할 때 백 스택을 관리하는 속성이다. 아래 그림과 같이 스택에 쌓여있다 생각하고 두 가지 속성을 알아보자.

  • popUpTo 지정된 대상에 도착할 때까지 대상 두 개 이상이 백 스택에서 없어진다. app:popUpTo="@id/startFragment"인 경우, StartFragment에 도달할 때까지 백 스택에 있는 대상들이 없어진다. 그래서 StartFragment으로 이동하면 실제로 StartFrament를 새 대상으로 백 스택에 추가하기 때문에 두 개나 백 스택에 생긴 것이다. 때문에 뒤로가기를 눌러 종료하려면 두 번 탭해야 한다!
  • popUpToInclusive 모든 대상을 백 스택에서 없앤다. app:popUpTo="@id/startFragment"app:popUpToInclusive="true"을 함께 활용하면 StartFragment가 하나만 생성된다. 때문에 한 번 탭해서 종료가 가능하다. cf) Design 탭에서 아래와 같이 활용한다. 이동하고자 하는 화살표를 클릭하고 속성을 설정하자.

plurals resource로 서로 다른 문자열 선택하기

// string.xml

<plurals name="cupcakes">
    <item quantity="one">%d cupcake</item>
    <item quantity="other">%d cupcakes</item>
</plurals>
// SummaryFragment.kt

fun sendOrder() {
    val numberOfCupcakes = sharedViewModel.quantity.value ?: 0
    val orderSummary = getString(
        R.string.order_details,
        resources.getQuantityString(R.plurals.cupcakes, numberOfCupcakes, numberOfCupcakes),
        sharedViewModel.flavor.value.toString(),
        sharedViewModel.date.value.toString(),
        sharedViewModel.price.value.toString()
    )

    val intent = Intent(Intent.ACTION_SEND)
        .setType("text/plain")
        .putExtra(Intent.EXTRA_SUBJECT, getString(R.string.new_cupcake_order))
        .putExtra(Intent.EXTRA_TEXT, orderSummary)

    if (activity?.packageManager?.resolveActivity(intent, 0) != null) {
        startActivity(intent)
    }
}

UnitTest, InstrumentationTest 폴더 만들기

유닛테스트인 경우,

계측테스트인 경우,

단위 테스트 실습

  • 특정 테스트 규칙 지정 다음 코드는 테스트할 객체(지금은 LiveData)가 기본 스레드를 호출하면 안 된다고 지정한다.
    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()
  • 테스트 코드 OrderViewModel의 setQuantity()가 호출될 때 quantity 객체가 업데이트되었는지 확인하려 한다.
    @Test
    fun quantity_twelve_cupcakes() {
       val viewModel = OrderViewModel() // 테스트할 ViewModel 인스턴스 생성
       viewModel.quantity.observeForever {} // 하단 설명
       viewModel.setQuantity(12) // 테스트 메서드에 값 입력
       assertEquals(12, viewModel.quantity.value) // 예상 값 추론하여 실제와 확인
    }
    observeForever → LiveData 객체의 값을 테스트할 때 객체를 관찰하기 위해 사용한다.

0개의 댓글