Jetpack Compose

Oct 11 2022 · Kotlin 1.7.10, Android 13, Android Studio Chipmunk

Part 1: Jetpack Compose Basics

09. Apply Error & Data Handling to the UI

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 08. Build Common UI Components - Part 3 Next episode: 10. Add Actions & Handlers

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 09. Apply Error & Data Handling to the UI

The student materials have been reviewed and are updated as of September 2022.

In ui/bookReviewDetails/BookReviewDetailsActivity file, within BookRevBookReviewDetailsInformationiewItem() composable function, replace CoilImage() composable by AsyncImage() composable with updated parameters. CoilImage composable is old and not compatible with current Jetpack Compose version.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

Demo

To make sure your forms don’t let the user store empty data, you need a way to disable actions or show errors, when the data is invalid. To do that, you need to apply error and data handling!

InputField(
  value = bookNameState.value,
        ...
  isInputValid = bookNameState.value.isNotEmpty()
)

InputField(
  value = bookDescriptionState.value,
        ...
  isInputValid = bookDescriptionState.value.isNotEmpty()
)

ActionButton(
  ...
  isEnabled = bookNameState.value.isNotEmpty()
      && bookDescriptionState.value.isNotEmpty()
      && _addBookState.value.genreId.isNotEmpty()
)
isInputValid = bookUrl.value.isNotEmpty()

...

isInputValid = bookNotes.value.isNotEmpty()

...

val pickedBook = _bookReviewState.value?.bookAndGenre

isEnabled = bookNotes.value.isNotEmpty() && bookUrl.value.isNotEmpty()
      && pickedBook != null && pickedBook != EMPTY_BOOK_AND_GENRE

private val _bookReviewDetailsState = mutableStateOf(EMPTY_BOOK_REVIEW)
private val _genreState = mutableStateOf(EMPTY_GENRE)
val bookReview = _bookReviewDetailsState.value
val genre = _genreState.value
Column(
  modifier = Modifier
    .fillMaxSize()
    .scrollable(rememberScrollState(), orientation = Orientation.Vertical),
  horizontalAlignment = Alignment.CenterHorizontally,
) {

  Spacer(modifier = Modifier.height(16.dp))
Card(
  modifier = Modifier
    .size(width = 200.dp, height = 300.dp),
  shape = RoundedCornerShape(16.dp),
  elevation = 16.dp
) {
  CoilImage(
    data = bookReview.review.imageUrl,
    contentScale = ContentScale.FillWidth,
    contentDescription = null
  )
}

Spacer(modifier = Modifier.height(16.dp))

Text(
  text = bookReview.book.name,
  fontWeight = FontWeight.Bold,
  fontSize = 18.sp
)

Spacer(modifier = Modifier.height(6.dp))

Text(
  text = genre.name,
  fontSize = 12.sp
)
      Spacer(modifier = Modifier.height(6.dp))

      RatingBar(
        modifier = Modifier.align(CenterHorizontally),
        range = 1..5,
        isSelectable = false,
        isLargeRating = false,
        currentRating = bookReview.review.rating
      )

      Spacer(modifier = Modifier.height(6.dp))

      Text(
        text = stringResource(
          id = R.string.last_updated_date,
          formatDateToText(bookReview.review.lastUpdatedDate)
        ),
        fontSize = 12.sp
      )

      Spacer(modifier = Modifier.height(8.dp))
      Spacer(
        modifier = Modifier
          .fillMaxWidth(0.9f)
          .height(1.dp)
          .background(
            brush = SolidColor(value = Color.LightGray),
            shape = RectangleShape
          )
      )

      Text(
        modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 8.dp, bottom = 8.dp),
        text = bookReview.review.notes,
        fontSize = 12.sp,
        fontStyle = FontStyle.Italic
      )

      Spacer(
        modifier = Modifier
          .fillMaxWidth(0.9f)
          .height(1.dp)
          .background(
            brush = SolidColor(value = Color.LightGray),
            shape = RectangleShape
          )
      )