이제 UI에서 누락된 사항인 물주기 정보 및 식물 설명의 마이그레이션을 완료하는 것이 더 쉬워졌다. 이전에 수행한 XML 코드 접근 방식을 동일하게 살펴보면, 이미 나머지 화면을 마이그레이션 할 수 있다.

fragment_plant_detail.xml에서 이전에 제거한 물주기 정보 XML 코드는 ID가 plant_watering_header 및 plant_watering인 두 개의 TextView로 구성된다.

<TextView
    android:id="@+id/plant_watering_header"
    ...
    android:layout_marginStart="@dimen/margin_small"
    android:layout_marginTop="@dimen/margin_normal"
    android:layout_marginEnd="@dimen/margin_small"
    android:gravity="center_horizontal"
    android:text="@string/watering_needs_prefix"
    android:textColor="?attr/colorAccent"
    android:textStyle="bold"
    ... />

<TextView
    android:id="@+id/plant_watering"
    ...
    android:layout_marginStart="@dimen/margin_small"
    android:layout_marginEnd="@dimen/margin_small"
    android:gravity="center_horizontal"
    app:wateringText="@{viewModel.plant.wateringInterval}"
    .../>

이전에 했던 작업과 유사하게 PlantWatering이라는 새 컴포저블을 만들고 텍스트를 추가하여 화면에 물주기 정보를 표시하자.

PlantDetailDescription.kt

@Composable
private fun PlantWatering(wateringInterval: Int) {
    Column(Modifier.fillMaxWidth()) {
        // 두 Text에 같은 modifier가 사용된다.
        val centerWithPaddingModifier = Modifier
            .padding(horizontal = dimensionResource(R.dimen.margin_small))
            .align(Alignment.CenterHorizontally)

        val normalPadding = dimensionResource(R.dimen.margin_normal)

        Text(
            text = stringResource(R.string.watering_needs_prefix),
            color = MaterialTheme.colors.primaryVariant,
            fontWeight = FontWeight.Bold,
            modifier = centerWithPaddingModifier.padding(top = normalPadding)
        )

        val wateringIntervalText = LocalContext.current.resources.getQuantityString(
            R.plurals.watering_needs_suffix, wateringInterval, wateringInterval
        )
        Text(
            text = wateringIntervalText,
            modifier = centerWithPaddingModifier.padding(bottom = normalPadding)
        )
    }
}

@Preview
@Composable
private fun PlantWateringPreview() {
    MaterialTheme {
        PlantWatering(7)
    }
}

미리보기로 보면 다음과 같다.

741b92db42c262df.png

몇가지 알아야 할 것들이 있다.

  • Text 컴포저블에서 수평 패딩(horizontal padding) 및 정렬(align) 같은 데코레이션을 공유하므로, Modifier를 로컬 변수(예: centerWithPaddingModifier)에 할당하여 Modifier를 재사용할 수 있다. Modifier는 일반 Kotlin 객체이므로 그렇게 할 수 있다.
  • 컴포즈의 MaterialTheme는 plant_watering_header에 사용된 colorAccent와 정확히 일치하지 않는다. 지금은 테마 섹션에서 개선할 MaterialTheme.colors.primaryVariant를 사용하겠다.

Warning: 컴포즈의 현재 버전에서는 dimension에서 수량화된 문자열을 가져오는 것을 지원하지 않는다. 그렇기 때문에 LocalContext.current.resources를 통해 액세스해야 한다. 해당 내용은 이미 이슈 트래커에 등록 된 상태다.

간단하게 하기 위해, 함수를 인라인으로 호출했지만 앱에서 이 작업을 수행하는 경우 재사용할 수 있도록 다른 함수로 추출한다.

모든 UI조각들을 함께 연결하고, PlantDetailContent에서도 PlantWatering을 호출해 보도록 한다. 처음에 제거한 ConstraintLayout XML 코드에는 Compose 코드에 포함해야 하는 16.dp의 여백이 있었다.

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/margin_normal">

PlantDetailContent에서 이름과 물주기 정보를 함께 표시하는 Column을 만들고, 이를 패딩으로 사용한다. 또한 배경색과 사용된 텍스트 색상이 적절하도록 이를 처리할 Surface를 추가하자.

PlantDetailDescription.kt

@Composable
fun PlantDetailContent(plant: Plant) {
    Surface {
        Column(Modifier.padding(dimensionResource(R.dimen.margin_normal))) {
            PlantName(plant.name)
            PlantWatering(plant.wateringInterval)
        }
    }
}

미리보기를 새로고침하면 다음과 같은 내용을 볼 수 있다.

97f35931b72c29b.png

donaricano-btn

카테고리: Compose

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.