From 4561b5d5773fd8f7f619c270c23d8bf0636e42cb Mon Sep 17 00:00:00 2001 From: SeniorZhai Date: Tue, 10 Mar 2026 10:37:42 +0800 Subject: [PATCH 1/5] fix: adjust bottom sheet inset spacing --- .../ui/common/GroupBottomSheetDialogFragment.kt | 4 +--- .../android/ui/common/UserBottomSheetDialogFragment.kt | 4 +--- .../ui/components/MemberUpgradePaymentButton.kt | 6 ++---- .../mixin/android/widget/BottomSheetDialogInsets.kt | 10 ++++++++++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt index 6ebf7294bd..f4b82dcb30 100644 --- a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt @@ -33,7 +33,6 @@ import one.mixin.android.extension.alertDialogBuilder import one.mixin.android.extension.dayTime import one.mixin.android.extension.dp import one.mixin.android.extension.getClipboardManager -import one.mixin.android.extension.getSafeAreaInsetsBottom import one.mixin.android.extension.localTime import one.mixin.android.extension.navigationBarHeight import one.mixin.android.extension.notNullWithElse @@ -405,8 +404,7 @@ class GroupBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment( .let { layout -> menuListLayout = layout binding.scrollContent.addView(layout) - val safeBottomHeight = layout.getSafeAreaInsetsBottom() - binding.scrollContent.setPadding(0,0,0,safeBottomHeight) + binding.scrollContent.setPadding(0, 0, 0, 0) binding.moreFl.setOnClickListener { if (behavior?.state == BottomSheetBehavior.STATE_COLLAPSED) { behavior?.state = BottomSheetBehavior.STATE_EXPANDED diff --git a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt index 3fbb105568..83f2ff7612 100644 --- a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt @@ -53,7 +53,6 @@ import one.mixin.android.extension.dp import one.mixin.android.extension.getClipboardManager import one.mixin.android.extension.getOtherPath import one.mixin.android.extension.getParcelableCompat -import one.mixin.android.extension.getSafeAreaInsetsBottom import one.mixin.android.extension.localTime import one.mixin.android.extension.navTo import one.mixin.android.extension.navigationBarHeight @@ -619,8 +618,7 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() list.createMenuLayout(requireContext()).let { layout -> menuListLayout = layout binding.scrollContent.addView(layout) - val safeBottomHeight = layout.getSafeAreaInsetsBottom() - binding.scrollContent.setPadding(0,0,0,safeBottomHeight) + binding.scrollContent.setPadding(0, 0, 0, 0) binding.moreFl.setOnClickListener { if (behavior?.state == BottomSheetBehavior.STATE_COLLAPSED) { behavior?.state = BottomSheetBehavior.STATE_EXPANDED diff --git a/app/src/main/java/one/mixin/android/ui/setting/ui/components/MemberUpgradePaymentButton.kt b/app/src/main/java/one/mixin/android/ui/setting/ui/components/MemberUpgradePaymentButton.kt index f98d65e80f..0db0b05823 100644 --- a/app/src/main/java/one/mixin/android/ui/setting/ui/components/MemberUpgradePaymentButton.kt +++ b/app/src/main/java/one/mixin/android/ui/setting/ui/components/MemberUpgradePaymentButton.kt @@ -64,7 +64,7 @@ fun MemberUpgradePaymentButton( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 30.dp) + .padding(start = 16.dp, end = 16.dp, top = 20.dp, bottom = 12.dp) ) { var buttonOffset by remember { mutableFloatStateOf(0f) } val interactionSource = remember { MutableInteractionSource() } @@ -95,7 +95,6 @@ fun MemberUpgradePaymentButton( Button( modifier = Modifier .fillMaxWidth() - .padding(16.dp) .height(48.dp) .offset(x = buttonOffset.dp), shape = RoundedCornerShape(24.dp), @@ -132,7 +131,7 @@ fun MemberUpgradePaymentButton( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 30.dp) + .padding(start = 16.dp, end = 16.dp, top = 20.dp, bottom = 12.dp) ) { val isPlanAvailable = isPlanAvailableInGooglePlay( selectedPlan, @@ -168,7 +167,6 @@ fun MemberUpgradePaymentButton( !isGooglePlayUnavailable), modifier = Modifier .fillMaxWidth() - .padding(16.dp) .height(48.dp), shape = RoundedCornerShape(24.dp), elevation = ButtonDefaults.elevation( diff --git a/app/src/main/java/one/mixin/android/widget/BottomSheetDialogInsets.kt b/app/src/main/java/one/mixin/android/widget/BottomSheetDialogInsets.kt index 0439956838..4e5d50480a 100644 --- a/app/src/main/java/one/mixin/android/widget/BottomSheetDialogInsets.kt +++ b/app/src/main/java/one/mixin/android/widget/BottomSheetDialogInsets.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.core.view.WindowInsetsCompat import androidx.core.view.updateLayoutParams import androidx.core.view.updateMargins +import androidx.core.view.updatePadding import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.internal.ViewUtils.doOnApplyWindowInsets @@ -27,4 +28,13 @@ internal fun BottomSheetDialog.applyBottomSheetContainerInsets(transparentStatus } findViewById(com.google.android.material.R.id.coordinator)?.fitsSystemWindows = false + findViewById(com.google.android.material.R.id.design_bottom_sheet)?.apply { + fitsSystemWindows = false + doOnApplyWindowInsets(this) { insetView, windowInsets, initialPadding -> + insetView.updatePadding( + bottom = initialPadding.bottom + windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom, + ) + windowInsets + } + } } From 83b67098e4391993f507b9f2c61957fa0294ad9a Mon Sep 17 00:00:00 2001 From: SeniorZhai Date: Tue, 10 Mar 2026 10:52:52 +0800 Subject: [PATCH 2/5] strip trailing zeros --- .../java/one/mixin/android/ui/wallet/InputFragment.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt b/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt index ebccc4b3e6..b7699fc325 100644 --- a/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt @@ -1184,7 +1184,12 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } else { baseValue.toPlainString() } - v = BigDecimal(v).multiply(percentageOfBalance).max(BigDecimal.ZERO).setScale(8, RoundingMode.DOWN).toPlainString() + v = BigDecimal(v) + .multiply(percentageOfBalance) + .max(BigDecimal.ZERO) + .setScale(8, RoundingMode.DOWN) + .stripTrailingZeros() + .toPlainString() updateUI() } @@ -1516,4 +1521,3 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } } } - From 4c306c00dbf086494107fb6c2e2c845fc48f84ce Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Thu, 12 Mar 2026 11:22:40 +0000 Subject: [PATCH 3/5] Initial plan From 8c59ee38d5e3b80930b3f3edd0ebd7ff4ee090d6 Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Thu, 12 Mar 2026 11:26:16 +0000 Subject: [PATCH 4/5] Fix bottom sheet peek height to use resolveBottomSheetPeekHeight consistently - Remove manual navigationBarHeight addition from bottom margins (safe area now handled by resolveBottomSheetPeekHeight) - Update UserBottomSheetDialogFragment and GroupBottomSheetDialogFragment to use resolveBottomSheetPeekHeight when setting peek height - Ensure consistent safe-area inset handling between initial and dynamic peek height updates Co-authored-by: crossle <1675131+crossle@users.noreply.github.com> --- .../ui/common/GroupBottomSheetDialogFragment.kt | 5 +++-- .../ui/common/UserBottomSheetDialogFragment.kt | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt index f4b82dcb30..9af03396b0 100644 --- a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt @@ -224,10 +224,11 @@ class GroupBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment( contentView.doOnPreDraw { binding.opsLl.updateLayoutParams { - bottomMargin = requireContext().navigationBarHeight() + 24.dp + bottomMargin = 24.dp } - behavior?.peekHeight = binding.title.height + binding.scrollContent.height - + val contentHeight = binding.title.height + binding.scrollContent.height - (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) } } diff --git a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt index 83f2ff7612..50bcf96e3d 100644 --- a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt @@ -218,12 +218,12 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() contentView.doOnPreDraw { if (!isAdded) return@doOnPreDraw binding.opLl.updateLayoutParams { - bottomMargin = requireContext().navigationBarHeight() + 24.dp + bottomMargin = 24.dp } - behavior?.peekHeight = - binding.title.height + + val contentHeight = binding.title.height + binding.scrollContent.height - (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) } }, ) @@ -285,12 +285,9 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() apps?.let { binding.avatarGroup.setApps(it) contentView.doOnPreDraw { - behavior?.peekHeight = - binding.title.height + binding.scrollContent.height - - ( - menuListLayout?.height - ?: 0 - ) - if (menuListLayout != null) 38.dp else 8.dp + val contentHeight = binding.title.height + binding.scrollContent.height - + (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) } } } From 12319ea55bd5366bcd23065744a7f93700d4f56c Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:04:23 +0000 Subject: [PATCH 5/5] Fix bottom sheet jitter and improve inset handling - Override getPeekHeight() in both UserBottomSheetDialogFragment and GroupBottomSheetDialogFragment to calculate correct initial collapsed height excluding menu layout - Make dynamic peek height updates conditional - only update when menu layout exists and is measured to avoid unnecessary recalculations - This eliminates rendering jitter by ensuring consistent peek height from initialization - Bottom insets are now properly handled by resolveBottomSheetPeekHeight() which adapts to devices with/without navigation bars Co-authored-by: SeniorZhai <5416585+SeniorZhai@users.noreply.github.com> --- .../common/GroupBottomSheetDialogFragment.kt | 35 ++++++++++++-- .../common/UserBottomSheetDialogFragment.kt | 46 ++++++++++++++++--- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt index 9af03396b0..b60b073d85 100644 --- a/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/GroupBottomSheetDialogFragment.kt @@ -110,6 +110,32 @@ class GroupBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment( FragmentGroupBottomSheetBinding.bind(contentView) } + override fun getPeekHeight( + contentView: View, + behavior: BottomSheetBehavior<*>, + ): Int { + val titleView = contentView.findViewById(R.id.title) ?: return 0 + val scrollContent = contentView.findViewById(R.id.scroll_content) ?: return 0 + + val width = contentView.measuredWidth.takeIf { it > 0 } ?: contentView.width + val widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY) + + titleView.measure( + widthSpec, + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + scrollContent.measure( + widthSpec, + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + + // Calculate height excluding menu layout and adding proper spacing + val menuHeight = menuListLayout?.measuredHeight ?: 0 + val spacing = if (menuHeight > 0) 38.dp else 8.dp + + return titleView.measuredHeight + scrollContent.measuredHeight - menuHeight - spacing + } + override fun setupDialog( dialog: Dialog, style: Int, @@ -226,9 +252,12 @@ class GroupBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment( binding.opsLl.updateLayoutParams { bottomMargin = 24.dp } - val contentHeight = binding.title.height + binding.scrollContent.height - - (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp - behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + // Update peek height only if menu layout exists and has been measured + if (menuListLayout != null && menuListLayout?.measuredHeight != 0) { + val contentHeight = binding.title.height + binding.scrollContent.height - + (menuListLayout?.height ?: 0) - 38.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + } } } diff --git a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt index 50bcf96e3d..6bc6cc586e 100644 --- a/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/common/UserBottomSheetDialogFragment.kt @@ -169,6 +169,32 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() FragmentUserBottomSheetBinding.bind(contentView) } + override fun getPeekHeight( + contentView: View, + behavior: BottomSheetBehavior<*>, + ): Int { + val titleView = contentView.findViewById(R.id.title) ?: return 0 + val scrollContent = contentView.findViewById(R.id.scroll_content) ?: return 0 + + val width = contentView.measuredWidth.takeIf { it > 0 } ?: contentView.width + val widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY) + + titleView.measure( + widthSpec, + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + scrollContent.measure( + widthSpec, + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + + // Calculate height excluding menu layout and adding proper spacing + val menuHeight = menuListLayout?.measuredHeight ?: 0 + val spacing = if (menuHeight > 0) 38.dp else 8.dp + + return titleView.measuredHeight + scrollContent.measuredHeight - menuHeight - spacing + } + override fun setupDialog( dialog: Dialog, style: Int, @@ -220,10 +246,13 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() binding.opLl.updateLayoutParams { bottomMargin = 24.dp } - val contentHeight = binding.title.height + - binding.scrollContent.height - - (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp - behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + // Update peek height only if menu layout exists and has been measured + if (menuListLayout != null && menuListLayout?.measuredHeight != 0) { + val contentHeight = binding.title.height + + binding.scrollContent.height - + (menuListLayout?.height ?: 0) - 38.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + } } }, ) @@ -285,9 +314,12 @@ class UserBottomSheetDialogFragment : MixinScrollableBottomSheetDialogFragment() apps?.let { binding.avatarGroup.setApps(it) contentView.doOnPreDraw { - val contentHeight = binding.title.height + binding.scrollContent.height - - (menuListLayout?.height ?: 0) - if (menuListLayout != null) 38.dp else 8.dp - behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + // Update peek height when apps are loaded + if (menuListLayout != null && menuListLayout?.measuredHeight != 0) { + val contentHeight = binding.title.height + binding.scrollContent.height - + (menuListLayout?.height ?: 0) - 38.dp + behavior?.peekHeight = requireContext().resolveBottomSheetPeekHeight(contentView, contentHeight) + } } } }