diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 51d6e0480..626b48887 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -145,6 +145,8 @@ dependencies { implementation(libs.glide) implementation(libs.accompanist.systemuicontroller) debugImplementation(libs.androidx.compose.ui.tooling) + //added + implementation(libs.androidx.compose.material) // Testing dependencies debugImplementation(libs.androidx.monitor) diff --git a/app/src/main/java/com/google/samples/apps/sunflower/compose/gallery/GalleryScreen.kt b/app/src/main/java/com/google/samples/apps/sunflower/compose/gallery/GalleryScreen.kt index e78bade63..0501add8c 100644 --- a/app/src/main/java/com/google/samples/apps/sunflower/compose/gallery/GalleryScreen.kt +++ b/app/src/main/java/com/google/samples/apps/sunflower/compose/gallery/GalleryScreen.kt @@ -16,13 +16,20 @@ package com.google.samples.apps.sunflower.compose.gallery +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.PullRefreshState +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -30,6 +37,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource @@ -49,6 +57,7 @@ import com.google.samples.apps.sunflower.viewmodels.GalleryViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +@OptIn(ExperimentalMaterialApi::class) @Composable fun GalleryScreen( viewModel: GalleryViewModel = hiltViewModel(), @@ -57,15 +66,19 @@ fun GalleryScreen( ) { GalleryScreen( plantPictures = viewModel.plantPictures, + isRefreshing = viewModel.isRefreshing, + pullRefreshState = rememberPullRefreshState(viewModel.isRefreshing, { viewModel.plantPictures }), onPhotoClick = onPhotoClick, onUpClick = onUpClick, ) } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterialApi::class) @Composable private fun GalleryScreen( plantPictures: Flow>, + isRefreshing: Boolean, + pullRefreshState: PullRefreshState, onPhotoClick: (UnsplashPhoto) -> Unit = {}, onUpClick: () -> Unit = {}, ) { @@ -75,25 +88,39 @@ private fun GalleryScreen( }, ) { padding -> val pagingItems: LazyPagingItems = plantPictures.collectAsLazyPagingItems() - LazyVerticalGrid( - columns = GridCells.Fixed(2), - modifier = Modifier.padding(padding), - contentPadding = PaddingValues(all = dimensionResource(id = R.dimen.card_side_margin)) - ) { - // TODO update this implementation once paging Compose supports LazyGridScope - // See: https://issuetracker.google.com/issues/178087310 - items( - count = pagingItems.itemCount, - key = { index -> - val photo = pagingItems[index] - "${ photo?.id ?: ""}${index}" - } - ) { index -> - val photo = pagingItems[index] ?: return@items - PhotoListItem(photo = photo) { - onPhotoClick(photo) + + Box( + modifier = Modifier + .fillMaxSize() + .pullRefresh(pullRefreshState) + ){ + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.padding(padding), + contentPadding = PaddingValues(all = dimensionResource(id = R.dimen.card_side_margin)) + ) { + // TODO update this implementation once paging Compose supports LazyGridScope + // See: https://issuetracker.google.com/issues/178087310 + items( + count = pagingItems.itemCount, + key = { index -> + val photo = pagingItems[index] + "${ photo?.id ?: ""}${index}" + } + ) { index -> + val photo = pagingItems[index] ?: return@items + PhotoListItem(photo = photo) { + onPhotoClick(photo) + } } } + + // adding pull refresh + PullRefreshComponent( + isRefreshing = isRefreshing, + state = pullRefreshState, + modifier = Modifier.align(Alignment.TopCenter) + ) } } } @@ -120,12 +147,17 @@ private fun GalleryTopBar( ) } +@OptIn(ExperimentalMaterialApi::class) @Preview @Composable private fun GalleryScreenPreview( @PreviewParameter(GalleryScreenPreviewParamProvider::class) plantPictures: Flow> ) { - GalleryScreen(plantPictures = plantPictures) + GalleryScreen( + plantPictures = plantPictures, + isRefreshing = false, + pullRefreshState = rememberPullRefreshState(false, { plantPictures }), + ) } private class GalleryScreenPreviewParamProvider : @@ -150,4 +182,19 @@ private class GalleryScreenPreviewParamProvider : ) ), ) +} + + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun PullRefreshComponent( + modifier: Modifier = Modifier, + isRefreshing: Boolean, + state: PullRefreshState +) { + PullRefreshIndicator( + modifier = modifier, + refreshing = isRefreshing, + state = state + ) } \ No newline at end of file diff --git a/app/src/main/java/com/google/samples/apps/sunflower/viewmodels/GalleryViewModel.kt b/app/src/main/java/com/google/samples/apps/sunflower/viewmodels/GalleryViewModel.kt index c58b8ac32..7fc16dc9d 100644 --- a/app/src/main/java/com/google/samples/apps/sunflower/viewmodels/GalleryViewModel.kt +++ b/app/src/main/java/com/google/samples/apps/sunflower/viewmodels/GalleryViewModel.kt @@ -32,6 +32,8 @@ class GalleryViewModel @Inject constructor( private var queryString: String? = savedStateHandle["plantName"] + val isRefreshing: Boolean = false + val plantPictures = repository.getSearchResultStream(queryString ?: "").cachedIn(viewModelScope) } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d22e1646c..c47b06dca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -119,9 +119,9 @@ retrofit2 = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofi retrofit2-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" } [plugins] -android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +android-application = { id = "com.android.application", version = "8.0.0" } android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } -android-test = { id = "com.android.test", version.ref = "androidGradlePlugin" } +android-test = { id = "com.android.test", version = "8.0.0" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }