要解决 Bottom Sheet 与内部 Fragment 的滚动冲突问题,可以尝试以下方法。这个方法是基于协调布局行为的思想,通过设置不同的滚动优先级来解决滚动冲突。

我们可以利用 CoordinatorLayout 和 BottomSheetBehavior,结合 NestedScrollView 或 NestedScrollingChild 接口来实现这个功能。这个思路是,当 BottomSheet 在全屏显示时,将内部 Fragment 的滚动优先级提升,当内部 Fragment 滚动到顶端时,再恢复 BottomSheet 的滚动。

1. 使用 CoordinatorLayout 和 BottomSheetBehavior

确保你的 FragmentA 使用了 CoordinatorLayout,并且 BottomSheet 的布局设置了 BottomSheetBehavior

<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
        
        <FragmentContainerView
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        
    </LinearLayout>
 
</androidx.coordinatorlayout.widget.CoordinatorLayout>

2. 处理滚动冲突

在 FragmentB 中,使用 NestedScrollView 或实现 NestedScrollingChild 接口来处理内部的滚动。

如果你使用的是 Jetpack Compose,那么你可以使用 Modifier.nestedScroll 来处理内部滚动。

3. 监听 BottomSheet 状态

在 FragmentA 中,监听 BottomSheet 的状态,并相应地调整滚动行为。

class FragmentA : Fragment() {
 
    private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>
 
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_a, container, false)
 
        val bottomSheet = view.findViewById<LinearLayout>(R.id.bottom_sheet)
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
 
        // Replace fragment when button is clicked
        val button = view.findViewById<Button>(R.id.button)
        button.setOnClickListener {
            childFragmentManager.beginTransaction()
                .replace(R.id.container, FragmentB())
                .commit()
        }
 
        return view
    }
 
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
 
        bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, newState: Int) {
                // Handle state changes
            }
 
            override fun onSlide(bottomSheet: View, slideOffset: Float) {
                // Handle sliding
            }
        })
    }
}

4. 在 FragmentB 中使用 Compose 的 NestedScroll

如果你在 FragmentB 中使用 Jetpack Compose,那么可以如下设置滚动处理:

class FragmentB : Fragment() {
 
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return ComposeView(requireContext()).apply {
            setContent {
                val nestedScrollConnection = remember {
                    object : NestedScrollConnection {
                        override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                            // Check BottomSheet state and handle scroll
                            return Offset.Zero
                        }
                    }
                }
 
                LazyColumn(
                    modifier = Modifier
                        .fillMaxSize()
                        .nestedScroll(nestedScrollConnection)
                ) {
                    items(100) {
                        Text(text = "Item #$it", modifier = Modifier.padding(16.dp))
                    }
                }
            }
        }
    }
}

总结

以上方法结合了 CoordinatorLayoutBottomSheetBehavior 和 NestedScrollView 或 NestedScrollingChild 接口,通过监听 BottomSheet 的状态来动态调整内部 Fragment 的滚动行为,以解决滚动冲突问题。在 Compose 中,可以通过 Modifier.nestedScroll 来实现类似效果。

这些方法可以帮助你在 Bottom Sheet 全屏显示时优先滚动内部的 Fragment,当内部 Fragment 滚动到顶端时再滚动 Bottom Sheet。

    转自:Bottom sheet与内嵌的fragment滚动冲突_编程语言-CSDN问答

    Logo

    火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

    更多推荐