diff options
| author | 2024-07-15 17:54:20 +0000 | |
|---|---|---|
| committer | 2024-07-15 17:54:20 +0000 | |
| commit | 1936da00dab547490ac4f0a349063fee3591d9d2 (patch) | |
| tree | a08d30be62ffaadf01c341fcbe53fd1d1ad7433a /java/src | |
| parent | af3b68fc7607383a9f6af57adf4196ba7b9c6a8f (diff) | |
| parent | af0301b4c0ecee359d729d8d072973752e2a2bcf (diff) | |
Merge "Limit max item aspect ratio" into main
Diffstat (limited to 'java/src')
| -rw-r--r-- | java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt index c40ed266..3c3381a2 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -46,13 +47,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.layout import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription @@ -106,42 +110,76 @@ private fun PreviewCarousel( initialFirstVisibleItemIndex = centerIdx, prefetchStrategy = remember { ShareouselLazyListPrefetchStrategy() } ) - // TODO: start item needs to be centered, check out ScalingLazyColumn impl or see if - // HorizontalPager works for our use-case - LazyRow( - state = carouselState, - horizontalArrangement = Arrangement.spacedBy(4.dp), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp), + var maxAspectRatio by remember { mutableStateOf(0f) } + + val horizontalPadding = 16.dp + Box( modifier = Modifier.fillMaxWidth() .height(dimensionResource(R.dimen.chooser_preview_image_height_tall)) - .systemGestureExclusion() - ) { - itemsIndexed(previews.previewModels, key = { _, model -> model.uri }) { index, model -> - - // Index if this is the element in the center of the viewing area, otherwise null - val previewIndex by remember { - derivedStateOf { - carouselState.layoutInfo.visibleItemsInfo - .firstOrNull { it.index == index } - ?.let { - val viewportCenter = carouselState.layoutInfo.viewportEndOffset / 2 - val halfPreviewWidth = it.size / 2 - val previewCenter = it.offset + halfPreviewWidth - val previewDistanceToViewportCenter = - abs(previewCenter - viewportCenter) - if (previewDistanceToViewportCenter <= halfPreviewWidth) index else null + .layout { measurable, constraints -> + val placeable = measurable.measure(constraints) + val aspectRatio = + if (placeable.height <= 0) { + 0f + } else { + val maxItemWidth = + maxOf(0, placeable.width - 2 * horizontalPadding.roundToPx()) + (maxItemWidth.toFloat() / placeable.height).coerceIn( + 0f, + MAX_ASPECT_RATIO + ) } + if (maxAspectRatio != aspectRatio) { + maxAspectRatio = aspectRatio + } + layout(placeable.width, placeable.height) { placeable.place(0, 0) } + }, + ) { + if (maxAspectRatio <= 0) { + // Do not compose the list until we know the viewport size + return@Box + } + // TODO: start item needs to be centered, check out ScalingLazyColumn impl or see if + // HorizontalPager works for our use-case + LazyRow( + state = carouselState, + horizontalArrangement = Arrangement.spacedBy(4.dp), + contentPadding = PaddingValues(start = horizontalPadding, end = horizontalPadding), + modifier = Modifier.fillMaxSize().systemGestureExclusion(), + ) { + itemsIndexed(previews.previewModels, key = { _, model -> model.uri }) { index, model -> + // Index if this is the element in the center of the viewing area, otherwise null + val previewIndex by remember { + derivedStateOf { + carouselState.layoutInfo.visibleItemsInfo + .firstOrNull { it.index == index } + ?.let { + val viewportCenter = carouselState.layoutInfo.viewportEndOffset / 2 + val halfPreviewWidth = it.size / 2 + val previewCenter = it.offset + halfPreviewWidth + val previewDistanceToViewportCenter = + abs(previewCenter - viewportCenter) + if (previewDistanceToViewportCenter <= halfPreviewWidth) { + index + } else { + null + } + } + } } - } - ShareouselCard(viewModel.preview(model, previewIndex, rememberCoroutineScope())) + ShareouselCard( + viewModel.preview(model, previewIndex, rememberCoroutineScope()), + maxAspectRatio, + ) + } } } } @Composable -private fun ShareouselCard(viewModel: ShareouselPreviewViewModel) { +private fun ShareouselCard(viewModel: ShareouselPreviewViewModel, maxAspectRatio: Float) { val bitmapLoadState by viewModel.bitmapLoadState.collectAsStateWithLifecycle() val selected by viewModel.isSelected.collectAsStateWithLifecycle(initialValue = false) val borderColor = MaterialTheme.colorScheme.primary @@ -162,8 +200,7 @@ private fun ShareouselCard(viewModel: ShareouselPreviewViewModel) { onValueChange = { scope.launch { viewModel.setSelected(it) } }, ) ) { state -> - // TODO: max ratio is actually equal to the viewport ratio - val aspectRatio = viewModel.aspectRatio.coerceIn(MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) + val aspectRatio = viewModel.aspectRatio.coerceIn(MIN_ASPECT_RATIO, maxAspectRatio) if (state is ValueUpdate.Value) { state.getOrDefault(null).let { bitmap -> ShareouselCard( |