三段式(抽屉式)底部弹窗BottomSheet,仿高德地图主页弹窗

  • Post author:
  • Post category:其他




需求

弹窗有收起状态,中间态,全部展开态。



方案

使用Google的BottomSheetBehavior。

具体使用可上官网了解:https://developer.android.google.cn/reference/com/google/android/material/bottomsheet/BottomSheetBehavior



实现

<!--父布局-->
<androidx.constraintlayout.widget.ConstraintLayout
     android:id="@+id/root"
     android:layout_width="match_parent"
     android:layout_height="match_parent" >
	<!--弹窗布局-->
	<LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:behavior_hideable="false"
        app:behavior_peekHeight="200dp"
        app:behavior_fitToContents="false"
        app:behavior_halfExpandedRatio="0.55"
        app:layout_behavior="@string/bottom_sheet_behavior">
        ...
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>



注意点:

弹窗的父布局必须是CoordinatorLayout,否则会报错



主要代码说明

		app:behavior_hideable="false"   
        app:behavior_peekHeight="200dp"
        app:behavior_fitToContents="false"
        app:behavior_halfExpandedRatio="0.55"
        app:layout_behavior="@string/bottom_sheet_behavior"
  • app:behavior_hideable=“false” 是否可隐藏,若为true下拉整个弹窗消失,即peekHeight将无用。
  • app:behavior_peekHeight=“200dp” 弹窗的默认状态高度,即三段式里的收起状态高度。
  • app:behavior_fitToContents=“false” 是否是两段式,默认true,只有完全展开和收起状态,没有中间态,false则为三段式。
  • app:behavior_halfExpandedRatio=“0.55” 中间态高度占完全展开弹窗的高度比,默认0.5。
  • app:layout_behavior=“@string/bottom_sheet_behavior” 设置该弹窗为google的bottom_sheet_behavior。



上代码



自定义View

继承CoordinatorLayout


/**
 * Created by zGui on 2022/7/11.
 * 三段式底部弹窗
 */
class ThreeBottomSheet : CoordinatorLayout {

    private var mBinding: IncludeBottomSheetBinding

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)

    constructor(context: Context, attributeSet: AttributeSet?, defStyle: Int) : super(
        context,
        attributeSet,
        defStyle
    ) {
        mBinding = DataBindingUtil.inflate(
            LayoutInflater.from(context),
            R.layout.include_bottom_sheet, this, true
        )

        val bottomSheetBehavior: BottomSheetBehavior<View> = BottomSheetBehavior.from<View>(mBinding.bottomSheet)
        //上拉框状态监听
        bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            //监听状态改变
            override fun onStateChanged(bottomSheet: View, newState: Int) {
//                when (newState) {
//                    BottomSheetBehavior.STATE_DRAGGING -> "STATE_DRAGGING" //过渡状态此时用户正在向上或者向下拖动bottom sheet
//                    BottomSheetBehavior.STATE_SETTLING -> "STATE_SETTLING" // 视图从脱离手指自由滑动到最终停下的这一小段时间
//                    BottomSheetBehavior.STATE_EXPANDED -> "STATE_EXPANDED" //处于完全展开的状态
//                    BottomSheetBehavior.STATE_HALF_EXPANDED -> "STATE_EXPANDED" //处于中间的状态
//                    BottomSheetBehavior.STATE_COLLAPSED -> "STATE_COLLAPSED" //默认的折叠状态
//                    BottomSheetBehavior.STATE_HIDDEN -> "STATE_HIDDEN" //下滑动完全隐藏 bottom sheet
//                }
            }

            //监听滑动的过程
            override fun onSlide(@NonNull bottomSheet: View, slideOffset: Float) {

            }
        })
        bottomSheetBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
    }
}



布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
        <import type="android.view.View"/>
    </data>

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:behavior_hideable="false"
        app:behavior_peekHeight="200dp"
        app:behavior_fitToContents="false"
        app:behavior_halfExpandedRatio="0.55"
        app:layout_behavior="@string/bottom_sheet_behavior">

		...
		<androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="@dimen/dp_64"
                />
               
    </LinearLayout>

</layout>



写在最后

此文章为个人开发时的记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇

————————————————

版权声明:转载请附上原文出处链接及本声明。

原文链接:

https://blog.csdn.net/weixin_44158429/article/details/125725097?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22125725097%22%2C%22source%22%3A%22weixin_44158429%22%7D&ctrtid=aQCHT



版权声明:本文为weixin_44158429原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。