summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-07-25 21:07:45 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-07-25 21:07:45 +0000
commit145833edf6a343efabfc5eaf37693145dd9fe45d (patch)
treece9dec54a00da8bec6526c8b984197f6b34372e0 /java
parent6dc6e9dd3706fa8238227bb978425f0095570f40 (diff)
parent068c395fd118c20632a5a77a0e28639863dc070b (diff)
Merge "Center initial item in Sharousel" into main
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt100
1 files changed, 67 insertions, 33 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 e8d75c8f..93ac90db 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
@@ -45,6 +45,7 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -71,6 +72,7 @@ import com.android.intentresolver.contentpreview.payloadtoggle.shared.model.Prev
import com.android.intentresolver.contentpreview.payloadtoggle.ui.viewmodel.ShareouselPreviewViewModel
import com.android.intentresolver.contentpreview.payloadtoggle.ui.viewmodel.ShareouselViewModel
import kotlin.math.abs
+import kotlin.math.min
import kotlinx.coroutines.launch
@Composable
@@ -104,44 +106,48 @@ private fun PreviewCarousel(
previews: PreviewsModel,
viewModel: ShareouselViewModel,
) {
- val centerIdx = previews.startIdx
- val carouselState =
- rememberLazyListState(
- initialFirstVisibleItemIndex = centerIdx,
- prefetchStrategy = remember { ShareouselLazyListPrefetchStrategy() }
- )
var maxAspectRatio by remember { mutableStateOf(0f) }
var viewportHeight by remember { mutableStateOf(0) }
-
- val horizontalPadding = 16.dp
+ var viewportCenter by remember { mutableStateOf(0) }
+ var horizontalPadding by remember { mutableStateOf(0.dp) }
Box(
modifier =
Modifier.fillMaxWidth()
.height(dimensionResource(R.dimen.chooser_preview_image_height_tall))
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
- val aspectRatio =
+ val (minItemWidth, maxAR) =
if (placeable.height <= 0) {
- 0f
+ 0f to 0f
} else {
- val maxItemWidth =
- maxOf(0, placeable.width - 2 * horizontalPadding.roundToPx())
- (maxItemWidth.toFloat() / placeable.height).coerceIn(
- 0f,
- MAX_ASPECT_RATIO
- )
+ val minItemWidth = (MIN_ASPECT_RATIO * placeable.height)
+ val maxItemWidth = maxOf(0, placeable.width - 32.dp.roundToPx())
+ val maxAR =
+ (maxItemWidth.toFloat() / placeable.height).coerceIn(
+ 0f,
+ MAX_ASPECT_RATIO
+ )
+ minItemWidth to maxAR
}
- maxAspectRatio = aspectRatio
+ viewportCenter = placeable.width / 2
+ maxAspectRatio = maxAR
viewportHeight = placeable.height
+ horizontalPadding = ((placeable.width - minItemWidth) / 2).toDp()
layout(placeable.width, placeable.height) { placeable.place(0, 0) }
},
) {
- if (maxAspectRatio <= 0) {
+ if (maxAspectRatio <= 0 && previews.previewModels.isNotEmpty()) {
// 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
+
+ var firstSelectedIndex by remember { mutableStateOf(null as Int?) }
+
+ val carouselState =
+ rememberLazyListState(
+ prefetchStrategy = remember { ShareouselLazyListPrefetchStrategy() },
+ )
+
LazyRow(
state = carouselState,
horizontalArrangement = Arrangement.spacedBy(4.dp),
@@ -149,26 +155,38 @@ private fun PreviewCarousel(
modifier = Modifier.fillMaxSize().systemGestureExclusion(),
) {
itemsIndexed(previews.previewModels, key = { _, model -> model.uri }) { index, model ->
+ val visibleItem by remember {
+ derivedStateOf {
+ carouselState.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
+ }
+ }
+
// 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
- }
+ visibleItem?.let {
+ val halfPreviewWidth = it.size / 2
+ val previewCenter = it.offset + halfPreviewWidth
+ val previewDistanceToViewportCenter =
+ abs(previewCenter - viewportCenter)
+ if (previewDistanceToViewportCenter <= halfPreviewWidth) {
+ index
+ } else {
+ null
}
+ }
}
}
+ val previewModel =
+ viewModel.preview(model, viewportHeight, previewIndex, rememberCoroutineScope())
+ val selected by
+ previewModel.isSelected.collectAsStateWithLifecycle(initialValue = false)
+
+ if (selected) {
+ firstSelectedIndex = min(index, firstSelectedIndex ?: Int.MAX_VALUE)
+ }
+
ShareouselCard(
viewModel.preview(
model,
@@ -180,6 +198,22 @@ private fun PreviewCarousel(
)
}
}
+
+ firstSelectedIndex?.let { index ->
+ LaunchedEffect(Unit) {
+ val visibleItem =
+ carouselState.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
+ val center =
+ with(carouselState.layoutInfo) {
+ ((viewportEndOffset - viewportStartOffset) / 2) + viewportStartOffset
+ }
+
+ carouselState.scrollToItem(
+ index = index,
+ scrollOffset = visibleItem?.size?.div(2)?.minus(center) ?: 0,
+ )
+ }
+ }
}
}