前言
上一篇文章中,谈到本系列的文章将讲解Android dialog、Material dialog,为何要谈论Material呢?开发过Flutter的开发者也许就会明白,Material Design框架Flutter也在用,而在其官网的介绍中是这样说的:Material 是 Google 创建的一个设计系统,旨在帮助团队为 Android、iOS、Flutter 和 Web 构建高质量的数字体验。可想而知,Material Design的应用有多广,这,便是博主将Material Dialog带入到本系列文章的原因。
Android常用对话框系列文章
【Android】常用对话框大全(一)Android Dialog
【Android】常用对话框大全(二)Material Dialog
【Android】常用对话框大全(三)自定义Dialog的三种方式(Theme,PopupWindow,Dialog)
目录
使用Material Design
请确保已导入以下依赖
implementation 'com.google.android.material:material:1.5.0'
MaterialAlertDialogBuilder系列
Marterial Dialog系列采用的是MaterialAlertDialogBuilder
类实现,其父类继承自AlertDiolag.Builder
,是AlertDialog.Builder
的扩
展,也就意味着AlertDialog.Buider
所拥有的属性,Material Dialog也可以使用。
需要注意的是,MaterialAlertDialogBuilder
的源码中,MaterialAlertDialogBuilder
类会根据当前主题的样式来修改当前的Dialog样式,要想展示Material Dialog真正的样式,需要将AndroidManifest.xml文件里的android:theme
修改为以下主题之一才能生效。
Theme | Describe |
---|---|
Theme.Material3.Light | 亮,亮色系主题白色为主 |
Theme.Material3.Light.NoActionBar | 亮,亮色系主题白色为主,且无ActionBar |
Theme.Material3.Dark | 暗,暗色系主题为主 |
Theme.Material3.Dark.NoActionBar | 暗,暗色系主题为主,且无ActionBar |
Theme.Material3.DayNight | 同Theme.Material3.Light |
Theme.Material3.DayNight.NoActionBar | 同Theme.Material3.Light.NoActionBar |
接下来编写代码,带大家见识一下Marterial Dialog长啥样。
提示对话框
实现代码:
MaterialAlertDialogBuilder(this)
.setTitle("消息对话框")
.setMessage("这是一个消息对话框!")
.setNegativeButton("不像") { dialog, which ->
showMessage(view,"真不像?")
}
.setPositiveButton("明明就是") { dialog: DialogInterface?, which: Int ->
showMessage(view,"明明就是")
}
.show()
use methods | Describe |
---|---|
setTitle(CharSequence title) | 设置对话框中显示的标题 |
setMessage(CharSequence message) | 设置要显示的消息 |
setNegativeButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的否定按钮时要调用的侦听器 |
setPositiveButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的肯定按钮时要调用的侦听器 |
左右按钮对话框
实现代码:
MaterialAlertDialogBuilder(this)
.setMessage("左右按钮对话框!")
.setNeutralButton("左") { dialog: DialogInterface?, which: Int -> showMessage(view,"左") }
.setPositiveButton("右") { dialog: DialogInterface?, which: Int -> showMessage(view,"右") }.show()
use methods | Describe |
---|---|
setMessage(CharSequence message) | 设置要显示的消息 |
setNeutralButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的中性按钮时要调用的侦听器 |
setPositiveButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的正按钮时要调用的侦听器 |
列表对话框
MaterialAlertDialogBuilder(this)
.setItems(items) { dialog: DialogInterface?, which: Int -> showMessage(view,"点击了列表对话框的 " + items[which]) }
.show()
use methods | Describe |
---|---|
setItems(CharSequence[] items, final OnClickListener listener) | 设置要在对话框中显示的项目列表作为内容,您将通过提供的侦听器通知您选择的项目 |
单选对话框
实现代码:
MaterialAlertDialogBuilder(this)
.setTitle("单选对话框")
.setSingleChoiceItems(items,0) { dialog: DialogInterface?, which: Int ->
singleSelectResult = items[which]
}
.setPositiveButton("确定") { dialog: DialogInterface?, which: Int ->
showMessage(view,singleSelectResult)
}
.show()
use methods | Describe |
---|---|
setTitle(CharSequence title) | 设置Dialog中显示的标题 |
setSingleChoiceItems(CharSequence[] items, int checkedItem, final OnClickListener listener) | 设置要在对话框中显示的项目列表作为内容,您将通过提供的侦听器收到所选项目的通知。该列表将在选中项目的文本右侧显示一个复选标记。单击列表中的项目不会关闭对话框。单击按钮将关闭对话框。 |
setPositiveButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的正按钮时要调用的侦听器 |
多选对话框
实现代码:
val bool = booleanArrayOf(false, false, false, false)
MaterialAlertDialogBuilder(this)
.setTitle("多选对话框")
.setMultiChoiceItems(items,bool) { dialog: DialogInterface?, which: Int, isChecked: Boolean -> }
.setPositiveButton("确定") { dialog: DialogInterface?, which: Int ->
var result = "选中了"
for (i in bool.indices) {
if (bool[i]) {
result += items[i]
}
}
showMessage(view,result)
}.show()
use methods | Describe |
---|---|
setTitle(CharSequence title) | 设置Dialog中显示的标题 |
setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, final OnMultiChoiceClickListener listener) | 设置要在对话框中显示的项目列表作为内容,您将通过提供的侦听器收到所选项目的通知。该列表将在每个选中项目的文本右侧显示一个复选标记。单击列表中的项目不会关闭对话框。单击按钮将关闭对话框。 |
setPositiveButton(CharSequence text, final OnClickListener listener) | 设置按下对话框的正按钮时要调用的侦听器 |
无半径对话框
MaterialAlertDialogBuilder
的对话框样式默认是带半径的,那我要去掉咋办?
MaterialAlertDialogBuilder
没有setRadius(int radius)
,需要换一种想法,比如,创建一个drawable改一下Background
试试。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景颜色为白色 -->
<solid android:color="@color/white"/>
</shape>
use methods | Describe |
---|---|
setBackground(Drawable background) | 修改对话框背景 |
效果如下:
MaterialAlertDialogBuilder属性
点击前往Android官网查看 MaterialAlertDialogBuilder 全部属性
日期时间系列
时间选择器
MaterialTimePicker
实现代码:
MaterialTimePicker.Builder().build().show(supportFragmentManager,"1")
MaterialTimePicker属性
点击前往Android官网查看 MaterialTimePicker 全部属性
日期选择器
MaterialDatePicker
实现代码:
MaterialDatePicker.Builder.datePicker().build().show(supportFragmentManager,"1")
MaterialDatePicker属性
点击前往Android官网查看 MaterialDatePicker 全部属性
底部对话框
底部对话框采用的是BottomSheetDialog
实现,使用方式简单,创建一个名为bottom_sheet_dialog.xml的layout文件,实例化一下BottomSheetDialog
就差不多完成啦!
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom|center_horizontal"
android:background="@null"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center"
android:text="标题"
android:textStyle="bold"
android:background="@null"/>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#C8C2C2" />
<TextView
android:layout_width="match_parent"
android:layout_height="35dp"
android:gravity="center"
android:text="Item 1" />
<TextView
android:layout_width="match_parent"
android:layout_height="35dp"
android:gravity="center"
android:text="Item 2" />
<TextView
android:layout_width="match_parent"
android:layout_height="35dp"
android:gravity="center"
android:text="Item 3" />
</LinearLayout>
val dialog = BottomSheetDialog (this);
dialog.setContentView(R.layout.bottom_sheet_dialog)
dialog.show()
效果如图:
BottomSheetDialog
的使用也是这样的简单,but,如果要尝试去修改它的背景的话,新人一般都会踩到一个坑,那就是背景的半径无法被修改,这是由于BottomSheetDialog
自带的背景造成的(与其它Dialog自定义半径所产生的问题类似),这时候我们需要去隐藏掉BottomSheetDialog
自带的背景。
but,BottomSheetDialog
并没有修改背景的方法,修改BottomSheetDialog
背景得依靠继承BottomSheetDialogFragment
类并重写onCreate(savedInstanceState: Bundle?)
、onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?)
并新建一个新的样式覆盖原有样式方可,如下:
class CustomBottomSheetDialogFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 可选的style:STYLE_NORMAL, STYLE_NO_TITLE, STYLE_NO_FRAME, STYLE_NO_INPUT.
setStyle(STYLE_NORMAL, R.style.BottomSheetDialog)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.bottom_sheet_dialog, container, false)
}
}
在themes.xml新建style
<!--实现BottomSheetDialog圆角效果-->
<style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/bottomSheetStyleWrapper</item>
</style>
<style name="bottomSheetStyleWrapper" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@android:color/transparent</item>
</style>
紧接着回到界面去实例化对话框并将其展示出来
val bottomSheetDialog = CustomBottomSheetDialogFragment()
bottomSheetDialog.show(supportFragmentManager, "1")
最终效果如下:
注意事项
1、开发初期就应该得考虑是否使用Material Design,一旦决定使用Material Design,App大部分组件都应该使用Material Design,尽量的去避免UI碎片化。
参考文档:
1、Material官网
2、Android Material组件入门
3、BottomSheetDialog 使用详解
4、Material Android官网(Dialogs)