一、效果图,不太清晰
本想一次全部录下来做成 gif 图,可惜高清 gif 图太大了,无法上传,只能换成普清模式,一次录一段,有更好的录制 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()
}
}
三、BottomSheetDialog 简单使用
3.1 简单对话框实现
setCancelable(false)//是否可以滑动关闭
setCanceledOnTouchOutside(true)//是否可以点击外部关闭
效果图:
对话框实现类:
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>
3.2 简单对话框实现圆角背景
- 1.效果图
对话框类 ```kotlin 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 = “第一个标签” }
}
- 3. 对话框布局
```kotlin
<?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>
圆角背景
<?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()
}
3.3 固定高度的 RecycelerView 对话框
对 RecyclerView 设置固定高度可以参考这个RecyclerView 设置固定数目 Item,这里简单做个示例,固定了高度,效果图如下:
对话框代码: ```kotlin class ListDialog(context: Context): BottomSheetDialog(context) { init {setContentView(R.layout.dialog_bottom)
setCancelable(false)//是否可以滑动关闭
setCanceledOnTouchOutside(true)//是否可以点击外部关闭
} val list = arrayListOf
(“测试数据一”,”测试数据二”,”测试数据三”,”测试数据四” ,”测试数据一”,”测试数据二”,”测试数据三”,”测试数据四”) 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)
}
}
简单布局:
```kotlin
<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>
3.4 占据全屏对话框
对话框占据全屏,初始暂时大约占据大半个屏幕,上滑占据全屏,效果如下:
对话框:
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 地址
- 当内容不够全屏时,设置全屏,并且设置下滑跳过折叠直接关闭。
对话框布局,设置最小高度超过屏幕高度,同时对话框里面设置如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_dialog_bottom_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- android:minHeight="900dp"设置最小高度实现全屏-->
</LinearLayout>
init {
setContentView(R.layout.dialog_bottom)
setCancelable(true)//是否可以滑动关闭
setCanceledOnTouchOutside(true)//是否可以点击外部关闭
// //设置全屏
// behavior.state = BottomSheetBehavior.STATE_EXPANDED
// //设置下滑跳过折叠态
// behavior.skipCollapsed = true
}
四、参考
BottomSheet、BottomSheetDialog使用详解
底部弹出抽屉BottomSheetDialogFragment,圆角背景,去除层叠,百分比设置高度【总结】
BottomSheetDialogFragment使用的注意点
Material Design 控件知识梳理(3) - BottomSheet && BottomSheetDialog && BottomSheetDialogFragment
Android评论框,类似抖音评论弹框