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

如何设置按钮组与Bottom Sheet顶部约束并跟随其滑动

实现方案

要实现按钮组跟随BottomSheet同步滑动的效果,不需要将按钮放入BottomSheet布局内,通过监听BottomSheet的滑动偏移动态更新按钮位置即可,具体实现步骤如下:

1. 调整主布局结构

删除主布局中冗余的layout_options_inside ConstraintLayout,直接将MaterialButtonToggleGroup作为CoordinatorLayout的直接子视图,修改后的主布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.mapbox.mapboxsdk.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            mapbox:mapbox_cameraTargetLat="40.73581"
            mapbox:mapbox_cameraTargetLng="-73.99155"
            mapbox:mapbox_cameraZoom="11"/>

    </FrameLayout>

    <include layout="@layout/bottom_sheet"/>

    <com.google.android.material.button.MaterialButtonToggleGroup
        android:id="@+id/toggleButtonGroup2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/transparent_white"
        android:orientation="vertical"
        app:singleSelection="true"
        android:layout_marginEnd="16dp"
        android:layout_gravity="end|bottom"
        android:layout_marginBottom="0dp"
        >

        <Button
            android:id="@+id/btnLeft"
            style="@style/ToggleButtonWithIconOnly"
            app:icon="@drawable/ic_outline_near_me_24"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btnCenter"
            style="@style/ToggleButtonWithIconOnly"
            app:icon="@drawable/ic_baseline_search_24"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </com.google.android.material.button.MaterialButtonToggleGroup>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

2. 添加滑动监听实现位置同步

在页面的Kotlin/Java代码中获取BottomSheetBehavior实例,添加滑动回调,根据滑动偏移动态更新按钮组的位置:

Kotlin示例代码

// 初始化视图
val bottomSheet = findViewById<LinearLayout>(R.id.bottomSheet)
val toggleGroup = findViewById<MaterialButtonToggleGroup>(R.id.toggleButtonGroup2)
val bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

// 视图加载完成后初始化位置
toggleGroup.post {
    val peekHeight = bottomSheetBehavior.peekHeight
    // 初始状态按钮底部对齐BottomSheet peek状态的顶部
    toggleGroup.translationY = -peekHeight.toFloat()
}

// 监听BottomSheet滑动
bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
    override fun onStateChanged(bottomSheet: View, newState: Int) {}

    override fun onSlide(bottomSheet: View, slideOffset: Float) {
        // slideOffset范围:-1(完全隐藏)、0(peek状态)、1(完全展开)
        val peekHeight = bottomSheetBehavior.peekHeight
        val maxSlideDistance = bottomSheet.height - peekHeight
        // 计算按钮需要偏移的距离,同步跟随BottomSheet移动
        val translationY = -peekHeight - (slideOffset * maxSlideDistance)
        toggleGroup.translationY = translationY.toFloat()
    }
})

3. 注意事项

  • 不要将按钮组放入BottomSheet布局内,否则超出BottomSheet边界的部分会被裁剪,无法实现悬浮在地图层上方的效果
  • 如果需要更优雅的全局复用实现,可以自定义CoordinatorLayout.Behavior绑定到按钮组,自动关联BottomSheet的滑动事件,无需手动添加监听

内容的提问来源于stack exchange,提问作者Thanawat test

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:06:03