summaryrefslogtreecommitdiff
path: root/java/src/com
diff options
context:
space:
mode:
author Andrey Yepin <ayepin@google.com> 2024-07-11 23:14:25 -0700
committer Andrey Yepin <ayepin@google.com> 2024-07-15 09:46:51 -0700
commitaf0301b4c0ecee359d729d8d072973752e2a2bcf (patch)
treed8a1d84fb91a4ba9c04bad4a4d5e293546448c63 /java/src/com
parent875c53f91e3bdc0814f25208b9b291809b3b6bcc (diff)
Limit max item aspect ratio
Limit max item aspect ratio to make sure it is always visible on the screen (incliding paddings) Fix: 351094699 Test: manual test Flag: EXEMPT bugfix Change-Id: I8748bb7ee1b9cde03da1f6d15075d04e806197db
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt91
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(