美文网首页Android
BottomSheetDialog可以拖动的底部对话框

BottomSheetDialog可以拖动的底部对话框

作者: FlyClound | 来源:发表于2020-08-09 21:53 被阅读0次

    一、效果图,不太清晰

    本想一次全部录下来做成 gif 图,可惜高清 gif 图太大了,无法上传,只能换成普清模式,一次录一段,有更好的录制 gif 图的方法可以留言告知。现在只能勉强看看。 iShot2020-08-0321.58.23.gifiShot2020-08-0321.58.23.gif

    二、实现类似抖音拖拽评论框效果

    首先布局的最外层要是CoordinatorLayout ,然后对话框的最外层要加上这三个属性:

    app:behavior_hideable="true"
    app:behavior_peekHeight="50dp"
    app:layout_behavior="@string/bottom_sheet_behavior"
    
    • app:behavior_hideable="true" ---> 可选设置,是否支持隐藏,设置为 false 或是不设置就是不支持,就不能调用隐藏的方法setState(BottomSheetBehavior.STATE_HIDDEN)
    • app:behavior_peekHeight="50dp" ---> 必选设置,收起高度,上图中黄色区域
    • app:layout_behavior 必选设置,设置以后才会有对话框效果

    完整的界面布局:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
    
                    <Button
                        android:id="@+id/btn_mddialog_bottomdialog"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="bottomSheetDialog"
                        android:textAllCaps="false"/>
    
                    <Button
                        android:id="@+id/btn_mddialog_bottomdialog2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="bottomSheetDialog"
                        android:textAllCaps="false"/>
    
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
    
                    <Button
                        android:id="@+id/btn_mddialog_list"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="bottomSheetDialog-list"
                        android:textAllCaps="false"/>
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <Button
                        android:id="@+id/btn_mddialog_expande"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="底部对话框展开"
                        android:textAllCaps="false"/>
                    <Button
                        android:id="@+id/btn_mddialog_hide"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="底部对话框隐藏"
                        android:textAllCaps="false"
                        android:layout_marginStart="5dp"
                        android:layout_marginEnd="5dp"/>
    
                    <Button
                        android:id="@+id/btn_mddialog_collose"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="底部对话框关闭"
                        android:textAllCaps="false"/>
                </LinearLayout>
    
            </LinearLayout>
    
    
    
        </androidx.core.widget.NestedScrollView>
    
    
    
    <!--    底部可以拉出的对话框,仿抖音-->
    <LinearLayout
        android:id="@+id/ll_mddialog_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:behavior_hideable="false"
        app:behavior_peekHeight="50dp"
        app:layout_behavior="@string/bottom_sheet_behavior"
        android:background="@color/white">
    
        <TextView
            android:id="@+id/tv_mddialog_bottomDialog"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="拖拽可以拉出对话框"
            android:textColor="@color/white"
            android:gravity="center"
            android:background="@color/yellow_FF9B52"/>
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_mddialog_bottom"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>
    
    </LinearLayout>
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    

    activity 部分:

    class MdDialogActivity: AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_mddialog)
    
            //bottomdialog test
            btn_mddialog_bottomdialog.setOnClickListener {
                showBottomDialog()
            }
            btn_mddialog_bottomdialog2.setOnClickListener {
                val dialog = SimpleDialog(this)
                dialog.show()
            }
    
            btn_mddialog_list.setOnClickListener {
                val dialog = ListDialog(this)
                dialog.show()
            }
    
            //把这个底部菜单和一个BottomSheetBehavior关联起来
            val behavior = BottomSheetBehavior.from(ll_mddialog_bottom)
            //底部对话框展开点击
            btn_mddialog_expande.setOnClickListener {
                if(behavior.state == BottomSheetBehavior.STATE_EXPANDED) {//展开不管
                    return@setOnClickListener
                }else{
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED)
                }
            }
            //底部对话框隐藏点击
            btn_mddialog_hide.setOnClickListener {
                behavior.setState(BottomSheetBehavior.STATE_HIDDEN)
            }
            //底部对话框关闭
            btn_mddialog_collose.setOnClickListener {
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
            }
            //初始化底部对话框列表
            initBottomList()
    //        tv_mddialog_bottomDialog.setOnClickListener {
    //            if(behavior.state == BottomSheetBehavior.STATE_EXPANDED) {//展开就隐藏
    //                behavior.setState(BottomSheetBehavior.STATE_HIDDEN)
    //            }else {//隐藏就展开
    //                behavior.setState(BottomSheetBehavior.STATE_EXPANDED)
    //            }
    //        }
    
    
    
        }
    
        val list = arrayListOf<String>("测试数据一","测试数据二","测试数据三","测试数据四"
            ,"测试数据一","测试数据二","测试数据三","测试数据四")
        val mAdapter by lazy { ListDialogAdapter() }
        private fun initBottomList() {
            rv_mddialog_bottom?.run {
                layoutManager = LinearLayoutManager(context)
                adapter = mAdapter
            }
            mAdapter.setList(list)
        }
    
        private fun showBottomDialog() {//可以滑动,向下滑动关闭
            val dialog = BottomSheetDialog(this)
            dialog.setCanceledOnTouchOutside(true)//设置点击空白处是否消失
            dialog.setCancelable(false)//设置是否可以滑动关闭
            val view = layoutInflater.inflate(R.layout.dialog_bottom_simple, null, false)
            dialog.setContentView(view)
            view.findViewById<TextView>(R.id.tv_dialog_bottom_simple_title)
                .text = "第一条标签"
            dialog.show()
        }
    }
    

    <a name="6sboB"></a>

    三、BottomSheetDialog 简单使用

    <a name="1wc5W"></a>

    3.1 简单对话框实现

    setCancelable(false)//是否可以滑动关闭
    setCanceledOnTouchOutside(true)//是否可以点击外部关闭
    
    效果图:<br /> image.pngimage.png

    <br />对话框实现类:

       private fun showBottomDialog() {//可以滑动,向下滑动关闭
            val dialog = BottomSheetDialog(this)
            dialog.setCanceledOnTouchOutside(true)//设置点击空白处是否消失
            val view = layoutInflater.inflate(R.layout.dialog_bottom_simple, null, false)
            dialog.setContentView(view)
            view.findViewById<TextView>(R.id.tv_dialog_bottom_simple_title)
                .text = "第一条标签"
            dialog.show()
        }
    

    简单对话框布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@color/white">
    
            <TextView
                android:id="@+id/tv_dialog_bottom_simple_title"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"/>
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
              />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
                />
        </LinearLayout>
    
    
    
    </RelativeLayout>
    

    <a name="0Hjom"></a>

    3.2 简单对话框实现圆角背景

    • 1.效果图
    image.pngimage.png
      1. 对话框类
    class SimpleDialog(context: Context): BottomSheetDialog(context) {
    
        init {
            setContentView(R.layout.dialog_bottom_simple_fillet)
        }
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            //布局内容动态设置
            tv_dialog_bottom_simple_title.text = "第一个标签"
        }
    
    
    }
    
      1. 对话框布局
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent"
       >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@drawable/bg_white_fillet_10">
    
            <TextView
                android:id="@+id/tv_dialog_bottom_simple_title"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"/>
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
              />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                android:text="设置备注及星标"
                android:gravity="center_vertical"
                android:paddingStart="@dimen/m10"
                />
        </LinearLayout>
    
    
    
    </RelativeLayout>
    
      1. 圆角背景
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    
        <solid android:color="@color/white"/>
    
        <corners android:topLeftRadius="@dimen/m10"
            android:topRightRadius="@dimen/m10"/>
    </shape>
    
    • 5.代码实现背景透明
        btn_mddialog_bottomdialog2.setOnClickListener {
                val dialog = SimpleDialog(this)
                //dialog.window!!.setDimAmount(0f)//;设置窗体背景透明
                //设置背景透明,以便显示圆角背景
                dialog.window!!.findViewById<View>(R.id.design_bottom_sheet)
                    .setBackgroundColor(Color.TRANSPARENT)
                dialog.show()
            }
    

    <a name="5yGuM"></a>

    3.3 固定高度的 RecycelerView 对话框

    对 RecyclerView 设置固定高度可以参考这个RecyclerView 设置固定数目 Item,这里简单做个示例,固定了高度,效果图如下:<br />

    iShot2020-08-0920.11.55.gifiShot2020-08-0920.11.55.gif <br />对话框代码:
    class ListDialog(context: Context): BottomSheetDialog(context) {
        init {
            setContentView(R.layout.dialog_bottom)
            setCancelable(false)//是否可以滑动关闭
            setCanceledOnTouchOutside(true)//是否可以点击外部关闭
        }
        val list = arrayListOf<String>("测试数据一","测试数据二","测试数据三","测试数据四"
        ,"测试数据一","测试数据二","测试数据三","测试数据四")
        private val mAdapter by lazy { ListDialogAdapter() }
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            rv_dialog_bottom_list.layoutManager = LinearLayoutManager(context)
            rv_dialog_bottom_list.setHasFixedSize(true)
            rv_dialog_bottom_list.adapter = mAdapter
            mAdapter.setList(list)
    
    
        }
    }
    

    简单布局:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_dialog_bottom_list"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>
    </RelativeLayout>
    

    简单的 Item 布局:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="50dp">
    
        <TextView
            android:id="@+id/tv_item_list_dialog_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="任意文字标签"
            android:gravity="center"
            />
    </RelativeLayout>
    

    adapter 很简单,就设置一个中间的文字就可以了。
    <a name="g48MM"></a>

    3.4 占据全屏对话框

    对话框占据全屏,初始暂时大约占据大半个屏幕,上滑占据全屏,效果如下:<br /> iShot2020-08-0920.12.22.gifiShot2020-08-0920.12.22.gif

    <br />对话框:

    class FullListDialog(context: Context): BottomSheetDialog(context) {
        init {
            setContentView(R.layout.dialog_bottom_list)
            setCancelable(true)
            setCanceledOnTouchOutside(true)
        }
    
        val list = arrayListOf<String>("测试数据一","测试数据二","测试数据三","测试数据四"
            ,"测试数据一","测试数据二","测试数据三","测试数据四","测试数据二","测试数据三","测试数据四"
            ,"测试数据一","测试数据二","测试数据三","测试数据四"  ,"测试数据一","测试数据二","测试数据三","测试数据四"
        )
    
        private val mAdapter by lazy { ListDialogAdapter() }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            rv_dialog_bottom_list_list.layoutManager = LinearLayoutManager(context)
            rv_dialog_bottom_list_list.setHasFixedSize(true)
            rv_dialog_bottom_list_list.adapter = mAdapter
            mAdapter.setList(list)
    
        }
    }
    

    对话框布局:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="列表标题"
            android:textSize="20dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:background="@color/white"
            android:padding="@dimen/m10"
            />
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_dialog_bottom_list_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    
    
    
    </LinearLayout>
    

    adapter 和 Item 布局和上面3.3的一样。
    demo 地址

    四、参考

    BottomSheet、BottomSheetDialog使用详解
    底部弹出抽屉BottomSheetDialogFragment,圆角背景,去除层叠,百分比设置高度【总结】
    BottomSheetDialogFragment使用的注意点
    Material Design 控件知识梳理(3) - BottomSheet && BottomSheetDialog && BottomSheetDialogFragment
    Android评论框,类似抖音评论弹框

    相关文章

      网友评论

        本文标题:BottomSheetDialog可以拖动的底部对话框

        本文链接:https://www.haomeiwen.com/subject/ncprdktx.html