You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现可拖动但不可关闭的Bottom Sheet?

实现可拖动但无法关闭的Bottom Sheet(Uber式交互)

要实现类似Uber应用中可拖动但无法关闭的Bottom Sheet,核心是利用Material Design的BottomSheetBehavior,通过配置参数和回调拦截来限制关闭行为,以下是具体实现步骤:

1. 布局配置

在CoordinatorLayout中定义Bottom Sheet,并关联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">

    <!-- 主界面内容 -->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- 你的主界面元素 -->
    </FrameLayout>

    <!-- 可拖动的Bottom Sheet -->
    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="#ffffff"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <!-- 拖动手柄(视觉提示) -->
        <View
            android:layout_width="48dp"
            android:layout_height="4dp"
            android:layout_marginVertical="8dp"
            android:background="#cccccc"
            android:layout_gravity="center_horizontal"/>

        <!-- Bottom Sheet内容区 -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="可拖动但无法关闭的面板"
            android:padding="16dp"/>

        <!-- 更多自定义内容 -->
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

2. 代码逻辑控制

通过BottomSheetBehavior配置拖动规则,禁止关闭行为:

// 获取BottomSheet实例及对应的Behavior
val bottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(bottomSheet)

// 允许拖动操作
behavior.isDraggable = true

// 禁止通过拖动或点击外部隐藏Bottom Sheet
behavior.isHideable = false

// 设置最小展开高度(确保面板始终保持可见)
behavior.peekHeight = resources.getDimensionPixelSize(R.dimen.bottom_sheet_min_height)

// 可选:限制面板只能在展开/半展开状态切换(如果需要多状态)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.setSkipCollapsed(false)

额外拦截逻辑(如果需要更精细控制)

如果isHideable = false不足以满足需求,可通过回调强制拦截隐藏状态:

behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
    override fun onStateChanged(bottomSheet: View, newState: Int) {
        // 当面板尝试进入隐藏状态时,强制切换回半展开状态
        if (newState == BottomSheetBehavior.STATE_HIDDEN) {
            behavior.state = BottomSheetBehavior.STATE_COLLAPSED
        }
    }

    override fun onSlide(bottomSheet: View, slideOffset: Float) {
        // 滑动过程中的自定义逻辑(可选)
    }
})

3. 依赖说明

确保项目中引入Material Design库:

implementation 'com.google.android.material:material:1.9.0' // 版本可按需选择

内容的提问来源于stack exchange,提问作者Andrew Piterov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:06:25