如何解决BottomSheetDialogFragment上滑未全屏时丢失顶部圆角问题
问题原因
该问题是Material Components BottomSheet的默认逻辑导致的:当BottomSheet滑动到顶部(距离系统状态栏小于圆角大小)时,会自动执行动画移除顶部圆角,再加上根布局用了match_parent、未禁用滑动/形状动画,就会出现滑动后圆角变直角的问题。
解决步骤
1. 修正布局高度
把fragment_item_selection.xml的根布局高度从match_parent改为wrap_content,让BottomSheet适配实际内容高度,不会默认撑满全屏:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" tools:context="com.example.ItemSelectionBottomSheetDialogFragment"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/item_list" android:layout_width="match_parent" android:layout_height="wrap_content" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> </FrameLayout>
2. 补充主题样式配置
在styles.xml的Widget.Demo.BottomSheet样式中添加属性,禁用形状动画、适配内容高度,可选禁用拖拽:
<style name="Widget.Demo.BottomSheet" parent="Widget.MaterialComponents.BottomSheet"> <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Demo</item> <!-- 适配内容高度,不会扩展到全屏 --> <item name="fitToContents">true</item> <!-- 禁用滑动时的形状变化动画,避免圆角被移除 --> <item name="disableShapeAnimations">true</item> <!-- 不需要滑动调整高度的话直接禁用拖拽 --> <item name="behavior_draggable">false</item> <!-- 可选:设置最大高度,避免内容过多时进入全屏 --> <item name="android:maxHeight">350dp</item> </style>
3. 代码强制固定配置(可选,双重保险)
在ItemSelectionBottomSheetDialogFragment的onStart方法中添加以下代码,避免样式未生效:
override fun onStart() { super.onStart() val dialog = dialog as? BottomSheetDialog ?: return val bottomSheet = dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) ?: return val behavior = BottomSheetBehavior.from(bottomSheet) // 强制禁用拖拽 behavior.isDraggable = false // 强制适配内容高度 behavior.isFitToContents = true // 禁用形状动画 behavior.disableShapeAnimations() // 固定为内容适配的状态,不会进入扩展全屏状态 behavior.state = BottomSheetBehavior.STATE_COLLAPSED }
内容的提问来源于stack exchange,提问作者Mehmed
相关产品推荐
相关产品推荐

