@@ -44,6 +44,7 @@ import androidx.compose.runtime.DisposableEffect
4444import androidx.compose.runtime.getValue
4545import androidx.compose.runtime.mutableStateOf
4646import androidx.compose.runtime.remember
47+ import androidx.compose.runtime.rememberCoroutineScope
4748import androidx.compose.runtime.setValue
4849import androidx.compose.ui.Alignment
4950import androidx.compose.ui.Modifier
@@ -59,7 +60,12 @@ import androidx.compose.ui.semantics.semantics
5960import androidx.compose.ui.tooling.preview.Preview
6061import androidx.compose.ui.tooling.preview.PreviewParameter
6162import androidx.compose.ui.unit.dp
62- import coil.compose.SubcomposeAsyncImage
63+ import coil.compose.AsyncImage
64+ import coil.compose.AsyncImagePainter
65+ import coil.compose.rememberAsyncImagePainter
66+ import coil.compose.rememberImagePainter
67+ import coil.request.ImageRequest
68+ import com.google.samples.apps.nowinandroid.core.designsystem.R.drawable
6369import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton
6470import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag
6571import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
@@ -74,7 +80,6 @@ import java.time.ZoneId
7480import java.time.format.DateTimeFormatter
7581import java.time.format.FormatStyle
7682import java.util.Locale
77- import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR
7883
7984/* *
8085 * [NewsResource] card used on the following screens: For You, Saved
@@ -149,32 +154,41 @@ fun NewsResourceCardExpanded(
149154fun NewsResourceHeaderImage (
150155 headerImageUrl : String? ,
151156) {
152- SubcomposeAsyncImage (
153- modifier = Modifier
154- .fillMaxWidth()
155- .height(180 .dp),
156- contentScale = ContentScale .Crop ,
157+ var isLoading by remember { mutableStateOf(true ) }
158+ var isError by remember { mutableStateOf(false ) }
159+ val imageLoader = rememberAsyncImagePainter(
157160 model = headerImageUrl,
158- // TODO b/226661685: Investigate using alt text of image to populate content description
159- contentDescription = null , // decorative image,
160- error = {
161- Image (
162- painter = painterResource(DesignsystemR .drawable.ic_placeholder_default),
163- contentDescription = " placeholder image" ,
164- )
165- },
166- loading = {
167- Box (
168- modifier = Modifier .size(180 .dp),
169- contentAlignment = Alignment .Center ,
170- ) {
171- CircularProgressIndicator (
172- Modifier .size(80 .dp),
173- color = MaterialTheme .colorScheme.tertiary,
174- )
175- }
161+ onState = { state ->
162+ isLoading = state is AsyncImagePainter .State .Loading
163+ isError = state is AsyncImagePainter .State .Error
176164 },
177165 )
166+ Box (
167+ modifier = Modifier
168+ .fillMaxWidth()
169+ .height(180 .dp),
170+ contentAlignment = Alignment .Center ,
171+ ) {
172+ if (isLoading) {
173+ // Display a progress bar while loading
174+ CircularProgressIndicator (
175+ modifier = Modifier
176+ .align(Alignment .Center )
177+ .size(80 .dp),
178+ color = MaterialTheme .colorScheme.tertiary,
179+ )
180+ }
181+
182+ Image (
183+ modifier = Modifier
184+ .fillMaxWidth()
185+ .height(180 .dp),
186+ contentScale = ContentScale .Crop ,
187+ painter = if (isError.not ()) imageLoader else painterResource(drawable.ic_placeholder_default),
188+ // TODO b/226661685: Investigate using alt text of image to populate content description
189+ contentDescription = null , // decorative image,
190+ )
191+ }
178192}
179193
180194@Composable
@@ -249,7 +263,6 @@ fun dateFormatted(publishDate: Instant): String {
249263 .withLocale(Locale .getDefault())
250264 .withZone(zoneId)
251265 .format(publishDate.toJavaInstant())
252-
253266}
254267
255268@Composable
0 commit comments