如何设置按钮组与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
相关产品推荐
相关产品推荐

