From 6f51afffad38c62a3f0f080b684c3842eccef62f Mon Sep 17 00:00:00 2001 From: LTFan Date: Thu, 25 Jan 2024 22:01:21 +0800 Subject: [PATCH 1/4] 1 --- .../commonMain/kotlin/ui/pages/root/SignIn.kt | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt index bea8d4e..bfc63a6 100644 --- a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt +++ b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt @@ -126,6 +126,7 @@ fun SignIn(component: SignInComponent) { SignInLayout( modifier = Modifier.fillMaxSize(), contentPadding = paddingValues, + scrollState = rememberScrollState(), header = { Text( text = "开启你的\n 美食之旅_", @@ -163,7 +164,7 @@ fun SignIn(component: SignInComponent) { }, additionalContent = { if (state is SignInComponent.ComponentState.SignIn) { - state.MoreMethods(modifier = Modifier.fillMaxWidth()) + state.MoreMethods(modifier = Modifier.fillMaxWidth(), scrollState = rememberScrollState()) } }, ) @@ -174,6 +175,7 @@ fun SignIn(component: SignInComponent) { fun SignInLayout( modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(0.dp), + scrollState: ScrollState, header: @Composable () -> Unit, content: @Composable () -> Unit, additionalContent: @Composable () -> Unit, @@ -192,8 +194,6 @@ fun SignInLayout( targetValue = if (animation == null) 0f else 1f, animationSpec = spring(stiffness = Spring.StiffnessLow) ) - val scrollState = rememberScrollState() - SubcomposeLayout( modifier = Modifier.alpha(firstPrintAnimation).offset(y = 32.dp * (1f - firstPrintAnimation)).then(modifier) ) { constraints -> @@ -203,6 +203,7 @@ fun SignInLayout( val contentPaddingRight = contentPadding.calculateRightPadding(layoutDirection).toPx() val contentPaddingBottom = contentPadding.calculateBottomPadding().toPx() val contentPaddingVertical = contentPaddingTop + contentPaddingBottom + val contentPaddingHorizontal = contentPaddingLeft + contentPaddingRight // == Layout sizes == val width = constraints.maxWidth @@ -230,20 +231,27 @@ fun SignInLayout( val additionalContentPaddingBottom = 16.dp.toPx() * animationSecondStageReversed + val additionalContentPaddingHorizontal = additionalContentPaddingLeft + additionalContentPaddingRight + val additionalContentCompatMediumWidth = width.toFloat() val additionalContentExpandedWidth = width * 2f / 9f val additionalContentWidth = - (additionalContentCompatMediumWidth + (additionalContentExpandedWidth - additionalContentCompatMediumWidth) * animationSecondStage - (additionalContentPaddingLeft + additionalContentPaddingRight)).roundToInt() + (additionalContentCompatMediumWidth + (additionalContentExpandedWidth - additionalContentCompatMediumWidth) * animationSecondStage - additionalContentPaddingHorizontal - contentPaddingHorizontal).roundToInt() .coerceAtLeast(0) + val additionalContentHeight = safeHeight - additionalContentPaddingBottom + val additionalContentConstraints = Constraints( minWidth = additionalContentWidth, maxWidth = additionalContentWidth, minHeight = 0, - maxHeight = safeHeight.roundToInt() + maxHeight = additionalContentHeight.roundToInt().coerceAtLeast(0) ) val additionalContentPlaceable = additionalContentMeasurable.measure(additionalContentConstraints) + val additionalContentActualWidth = additionalContentPlaceable.width + additionalContentPaddingHorizontal + contentPaddingHorizontal + val additionalContentActualHeight = additionalContentPlaceable.height + additionalContentPaddingBottom + // == Measure main == val mainBottomSpace = ((additionalContentPlaceable.height + additionalContentPaddingBottom) * animationSecondStageReversed) @@ -272,21 +280,10 @@ fun SignInLayout( val mainConstraints = Constraints.fixed(width = mainWidth, height = height) val mainPlaceable = mainMeasurable.measure(mainConstraints) - // == Scrollbar == - val scrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) - - val scrollbarPlaceable = subcompose("scrollBar") { - VerticalScrollbar(scrollState = scrollState) - }.firstOrNull() - ?.measure(Constraints(maxWidth = mainWidth, minHeight = scrollbarHeight, maxHeight = scrollbarHeight)) - - val scrollbarX = scrollbarPlaceable?.let { mainWidth - scrollbarPlaceable.width } - val scrollbarY = contentPaddingTop.roundToInt() - // == Place == val additionalContentCompatMediumX = 0f val additionalContentX = - additionalContentCompatMediumX + (mainPlaceable.width - additionalContentCompatMediumX) * animationSecondStage + additionalContentPaddingLeft + additionalContentCompatMediumX + (mainPlaceable.width - additionalContentCompatMediumX) * animationSecondStage + additionalContentPaddingLeft + contentPaddingLeft val additionalContentCompatMediumY = (height - additionalContentPlaceable.height).toFloat() - additionalContentPaddingBottom - contentPaddingBottom @@ -316,11 +313,38 @@ fun SignInLayout( val additionalContentBackgroundY = additionalContentY + (height - additionalContentY) * animationSecondStage + // == Scrollbars == + val mainScrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) + + val mainScrollbarPlaceable = subcompose("mainScrollBar") { + VerticalScrollbar(scrollState = scrollState) + }.firstOrNull()?.measure( + Constraints(maxWidth = mainWidth, minHeight = mainScrollbarHeight, maxHeight = mainScrollbarHeight) + ) + + val mainScrollbarX = mainScrollbarPlaceable?.let { mainWidth - mainScrollbarPlaceable.width } + val mainScrollbarY = contentPaddingTop.roundToInt() + + val additionalContentScrollbarHeight = additionalContentActualHeight.roundToInt().coerceAtLeast(0) + + val additionalContentScrollbarPlaceable = subcompose("additionalContentScrollBar") { + VerticalScrollbar(scrollState = scrollState) + }.firstOrNull()?.measure( + Constraints( + maxWidth = additionalContentActualWidth.roundToInt().coerceAtLeast(0), + minHeight = additionalContentScrollbarHeight, + maxHeight = additionalContentScrollbarHeight + ) + ) + + val additionalContentScrollbarX = additionalContentScrollbarPlaceable?.let { additionalContentActualWidth - additionalContentScrollbarPlaceable.width } + layout(width, height) { mainPlaceable.placeRelative(0, 0) - scrollbarX?.let { scrollbarPlaceable.placeRelative(scrollbarX, scrollbarY) } + mainScrollbarX?.let { mainScrollbarPlaceable.placeRelative(mainScrollbarX, mainScrollbarY) } additionalContentBackgroundPlaceable.placeRelative(0, additionalContentBackgroundY.roundToInt()) additionalContentPlaceable.placeRelative(additionalContentX.roundToInt(), additionalContentY.roundToInt()) + additionalContentScrollbarX?.let { additionalContentScrollbarPlaceable.placeRelative(additionalContentScrollbarX.roundToInt(), additionalContentY.roundToInt()) } } } @@ -483,9 +507,7 @@ fun SignInMainLayout( } @Composable -fun SignInComponent.ComponentState.SignIn.MoreMethods(modifier: Modifier = Modifier) { - val scrollState = rememberScrollState() - +fun SignInComponent.ComponentState.SignIn.MoreMethods(modifier: Modifier = Modifier, scrollState: ScrollState) { SubcomposeLayout { constraints -> val buttons = subcompose("buttons") { Column(modifier = modifier.verticalScroll(state = scrollState)) { From 045a8857c2c5e2c1a272088f966b2594fcf468e0 Mon Sep 17 00:00:00 2001 From: LTFan Date: Thu, 25 Jan 2024 22:07:30 +0800 Subject: [PATCH 2/4] 1 --- .../commonMain/kotlin/ui/pages/root/SignIn.kt | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt index bfc63a6..b5e2178 100644 --- a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt +++ b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt @@ -164,7 +164,7 @@ fun SignIn(component: SignInComponent) { }, additionalContent = { if (state is SignInComponent.ComponentState.SignIn) { - state.MoreMethods(modifier = Modifier.fillMaxWidth(), scrollState = rememberScrollState()) + state.MoreMethods(modifier = Modifier.fillMaxWidth()) } }, ) @@ -313,38 +313,22 @@ fun SignInLayout( val additionalContentBackgroundY = additionalContentY + (height - additionalContentY) * animationSecondStage - // == Scrollbars == - val mainScrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) + // == Scrollbar == + val scrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) - val mainScrollbarPlaceable = subcompose("mainScrollBar") { + val scrollbarPlaceable = subcompose("scrollBar") { VerticalScrollbar(scrollState = scrollState) - }.firstOrNull()?.measure( - Constraints(maxWidth = mainWidth, minHeight = mainScrollbarHeight, maxHeight = mainScrollbarHeight) - ) - - val mainScrollbarX = mainScrollbarPlaceable?.let { mainWidth - mainScrollbarPlaceable.width } - val mainScrollbarY = contentPaddingTop.roundToInt() - - val additionalContentScrollbarHeight = additionalContentActualHeight.roundToInt().coerceAtLeast(0) - - val additionalContentScrollbarPlaceable = subcompose("additionalContentScrollBar") { - VerticalScrollbar(scrollState = scrollState) - }.firstOrNull()?.measure( - Constraints( - maxWidth = additionalContentActualWidth.roundToInt().coerceAtLeast(0), - minHeight = additionalContentScrollbarHeight, - maxHeight = additionalContentScrollbarHeight - ) - ) + }.firstOrNull() + ?.measure(Constraints(maxWidth = mainWidth, minHeight = scrollbarHeight, maxHeight = scrollbarHeight)) - val additionalContentScrollbarX = additionalContentScrollbarPlaceable?.let { additionalContentActualWidth - additionalContentScrollbarPlaceable.width } + val scrollbarX = scrollbarPlaceable?.let { mainWidth - scrollbarPlaceable.width } + val scrollbarY = contentPaddingTop.roundToInt() layout(width, height) { mainPlaceable.placeRelative(0, 0) - mainScrollbarX?.let { mainScrollbarPlaceable.placeRelative(mainScrollbarX, mainScrollbarY) } + scrollbarX?.let { scrollbarPlaceable.placeRelative(scrollbarX, scrollbarY) } additionalContentBackgroundPlaceable.placeRelative(0, additionalContentBackgroundY.roundToInt()) additionalContentPlaceable.placeRelative(additionalContentX.roundToInt(), additionalContentY.roundToInt()) - additionalContentScrollbarX?.let { additionalContentScrollbarPlaceable.placeRelative(additionalContentScrollbarX.roundToInt(), additionalContentY.roundToInt()) } } } @@ -507,7 +491,9 @@ fun SignInMainLayout( } @Composable -fun SignInComponent.ComponentState.SignIn.MoreMethods(modifier: Modifier = Modifier, scrollState: ScrollState) { +fun SignInComponent.ComponentState.SignIn.MoreMethods(modifier: Modifier = Modifier) { + val scrollState = rememberScrollState() + SubcomposeLayout { constraints -> val buttons = subcompose("buttons") { Column(modifier = modifier.verticalScroll(state = scrollState)) { From e2fbd483bdaa0a6042b891a132d31edb203d3fb1 Mon Sep 17 00:00:00 2001 From: LTFan Date: Thu, 25 Jan 2024 22:12:05 +0800 Subject: [PATCH 3/4] 1 --- composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt index b5e2178..736c3e5 100644 --- a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt +++ b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt @@ -126,7 +126,6 @@ fun SignIn(component: SignInComponent) { SignInLayout( modifier = Modifier.fillMaxSize(), contentPadding = paddingValues, - scrollState = rememberScrollState(), header = { Text( text = "开启你的\n 美食之旅_", @@ -175,7 +174,8 @@ fun SignIn(component: SignInComponent) { fun SignInLayout( modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(0.dp), - scrollState: ScrollState, + scrollState: ScrollState = rememberScrollState(), + additionalContentScrollState: ScrollState = rememberScrollState(), header: @Composable () -> Unit, content: @Composable () -> Unit, additionalContent: @Composable () -> Unit, From 2ee21a3fe0dba0aec561c5baf8adeeecf91dc6b7 Mon Sep 17 00:00:00 2001 From: LTFan Date: Fri, 26 Jan 2024 20:14:50 +0800 Subject: [PATCH 4/4] ok --- .../commonMain/kotlin/ui/pages/root/SignIn.kt | 176 ++++++++++-------- 1 file changed, 95 insertions(+), 81 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt index 736c3e5..c13b886 100644 --- a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt +++ b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt @@ -218,20 +218,25 @@ fun SignInLayout( val animationSecondStageReversed = 1f - animationSecondStage // == Measure additional content == - val additionalContentMeasurable = - subcompose(slotId = "additionalContent", content = additionalContent).firstOrNull() - ?: return@SubcomposeLayout layout(0, 0) {} + val additionalContentMeasurable = subcompose(slotId = "additionalContent") { + Box(modifier = Modifier.verticalScroll(state = additionalContentScrollState)) { + additionalContent() + } + }.firstOrNull() ?: return@SubcomposeLayout layout(0, 0) {} val additionalContentCompatMediumPaddingLeft = 32.dp.toPx() val additionalContentExpandedPaddingLeft = 16.dp.toPx() val additionalContentPaddingLeft = additionalContentCompatMediumPaddingLeft + (additionalContentExpandedPaddingLeft - additionalContentCompatMediumPaddingLeft) * animationSecondStage + val additionalContentPaddingTop = 8.dp.toPx() * animationSecondStageReversed + val additionalContentPaddingRight = 32.dp.toPx() val additionalContentPaddingBottom = 16.dp.toPx() * animationSecondStageReversed val additionalContentPaddingHorizontal = additionalContentPaddingLeft + additionalContentPaddingRight + val additionalContentPaddingVertical = additionalContentPaddingTop + additionalContentPaddingBottom val additionalContentCompatMediumWidth = width.toFloat() val additionalContentExpandedWidth = width * 2f / 9f @@ -239,7 +244,7 @@ fun SignInLayout( (additionalContentCompatMediumWidth + (additionalContentExpandedWidth - additionalContentCompatMediumWidth) * animationSecondStage - additionalContentPaddingHorizontal - contentPaddingHorizontal).roundToInt() .coerceAtLeast(0) - val additionalContentHeight = safeHeight - additionalContentPaddingBottom + val additionalContentHeight = safeHeight - additionalContentPaddingVertical val additionalContentConstraints = Constraints( minWidth = additionalContentWidth, @@ -249,12 +254,13 @@ fun SignInLayout( ) val additionalContentPlaceable = additionalContentMeasurable.measure(additionalContentConstraints) - val additionalContentActualWidth = additionalContentPlaceable.width + additionalContentPaddingHorizontal + contentPaddingHorizontal - val additionalContentActualHeight = additionalContentPlaceable.height + additionalContentPaddingBottom + val additionalContentActualWidth = + additionalContentPlaceable.width + additionalContentPaddingHorizontal + contentPaddingHorizontal + val additionalContentActualHeight = additionalContentPlaceable.height + additionalContentPaddingVertical // == Measure main == val mainBottomSpace = - ((additionalContentPlaceable.height + additionalContentPaddingBottom) * animationSecondStageReversed) + ((additionalContentPlaceable.height + additionalContentPaddingVertical) * animationSecondStageReversed) val mainMeasurable = subcompose("main") { SignInMainLayout( @@ -313,22 +319,45 @@ fun SignInLayout( val additionalContentBackgroundY = additionalContentY + (height - additionalContentY) * animationSecondStage - // == Scrollbar == - val scrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) + // == Scrollbars == + val mainScrollbarHeight = (safeHeight - mainBottomSpace).roundToInt().coerceAtLeast(0) - val scrollbarPlaceable = subcompose("scrollBar") { + val mainScrollbarPlaceable = subcompose("mainScrollBar") { VerticalScrollbar(scrollState = scrollState) - }.firstOrNull() - ?.measure(Constraints(maxWidth = mainWidth, minHeight = scrollbarHeight, maxHeight = scrollbarHeight)) + }.firstOrNull()?.measure( + Constraints( + maxWidth = mainWidth, minHeight = mainScrollbarHeight, maxHeight = mainScrollbarHeight + ) + ) + + val mainScrollbarX = mainScrollbarPlaceable?.let { mainWidth - mainScrollbarPlaceable.width } + val mainScrollbarY = contentPaddingTop.roundToInt() + + val additionalContentScrollbarHeight = additionalContentActualHeight.roundToInt().coerceAtLeast(0) + + val additionalContentScrollbarPlaceable = subcompose("additionalContentScrollbar") { + VerticalScrollbar(scrollState = additionalContentScrollState) + }.firstOrNull()?.measure( + Constraints( + maxWidth = additionalContentWidth, + minHeight = additionalContentScrollbarHeight, + maxHeight = additionalContentScrollbarHeight + ) + ) - val scrollbarX = scrollbarPlaceable?.let { mainWidth - scrollbarPlaceable.width } - val scrollbarY = contentPaddingTop.roundToInt() + val additionalContentScrollbarX = + additionalContentScrollbarPlaceable?.let { additionalContentX - additionalContentPaddingLeft - contentPaddingLeft + additionalContentActualWidth - additionalContentScrollbarPlaceable.width } layout(width, height) { mainPlaceable.placeRelative(0, 0) - scrollbarX?.let { scrollbarPlaceable.placeRelative(scrollbarX, scrollbarY) } + mainScrollbarX?.let { mainScrollbarPlaceable.placeRelative(mainScrollbarX, mainScrollbarY) } additionalContentBackgroundPlaceable.placeRelative(0, additionalContentBackgroundY.roundToInt()) additionalContentPlaceable.placeRelative(additionalContentX.roundToInt(), additionalContentY.roundToInt()) + additionalContentScrollbarX?.let { + additionalContentScrollbarPlaceable.placeRelative( + additionalContentScrollbarX.roundToInt(), additionalContentY.roundToInt() + ) + } } } @@ -492,73 +521,58 @@ fun SignInMainLayout( @Composable fun SignInComponent.ComponentState.SignIn.MoreMethods(modifier: Modifier = Modifier) { - val scrollState = rememberScrollState() - - SubcomposeLayout { constraints -> - val buttons = subcompose("buttons") { - Column(modifier = modifier.verticalScroll(state = scrollState)) { - FilledTonalButton( - onClick = onGuestSignIn, - modifier = Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.large, - ) { - Icon( - imageVector = Icons.Default.NoAccounts, - contentDescription = null, - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(text = "游客登录") - } - FilledTonalButton( - onClick = onFaceSignIn, - modifier = Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.large, - ) { - Icon( - imageVector = Icons.Default.Face, - contentDescription = null, - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(text = "人脸登录") - } - TextButton( - onClick = ::switchShowMoreSignInOptions, - modifier = Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.large, - ) { - Icon( - imageVector = Icons.Default.MoreHoriz, - contentDescription = null, - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(text = "更多登录选项") - } - AnimatedVisibility( - visible = showMoreSignInOptions, - ) { - FilledTonalButton( - onClick = ::onAdminSignIn, - modifier = Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.large, - ) { - Icon( - imageVector = Icons.Default.AdminPanelSettings, - contentDescription = null, - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(text = "管理员登录") - } - } + Column(modifier = modifier) { + FilledTonalButton( + onClick = onGuestSignIn, + modifier = Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.large, + ) { + Icon( + imageVector = Icons.Default.NoAccounts, + contentDescription = null, + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(text = "游客登录") + } + FilledTonalButton( + onClick = onFaceSignIn, + modifier = Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.large, + ) { + Icon( + imageVector = Icons.Default.Face, + contentDescription = null, + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(text = "人脸登录") + } + TextButton( + onClick = ::switchShowMoreSignInOptions, + modifier = Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.large, + ) { + Icon( + imageVector = Icons.Default.MoreHoriz, + contentDescription = null, + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(text = "更多登录选项") + } + AnimatedVisibility( + visible = showMoreSignInOptions, + ) { + FilledTonalButton( + onClick = ::onAdminSignIn, + modifier = Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.large, + ) { + Icon( + imageVector = Icons.Default.AdminPanelSettings, + contentDescription = null, + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(text = "管理员登录") } - }.first().measure(constraints) - - val scrollBar = subcompose("scrollBar") { - VerticalScrollbar(scrollState = scrollState) - }.firstOrNull()?.measure(Constraints.fixedHeight(buttons.height)) - - layout(buttons.width, buttons.height) { - buttons.placeRelative(0, 0) - scrollBar?.placeRelative(buttons.width - scrollBar.width, 0) } } }