【Android Dialog】Dialog

在这里插入图片描述
在这里插入图片描述

AlertDialog

Dialog类是所有弹窗的父类,官方建议我们不要直接实例化它,而是使用其子类来获取实例。AlertDialog是系统提供的一个直接子类,它能帮助我们快速构建出不同类型的弹窗。接下来就看下各种类型弹窗的使用。

1、普通对话框
/**
 * AlertDialog默认UI样式
 * */
private fun showNormalAlertDialog() {
    val builder = AlertDialog.Builder(this)
        .setIcon(R.mipmap.ic_launcher)
        .setTitle("Dialog Title")
        .setMessage("Dialog Message")
        .setPositiveButton("Sure", object : DialogInterface.OnClickListener {
            override fun onClick(dialog: DialogInterface?, which: Int) {
                Toast.makeText(applicationContext, "Sure", Toast.LENGTH_SHORT).show()
            }
        })
        .setNegativeButton("Cancel", object : DialogInterface.OnClickListener {
            override fun onClick(dialog: DialogInterface?, which: Int) {
                Toast.makeText(applicationContext, "Cancel", Toast.LENGTH_SHORT).show()
            }
        })
        //Neutral按钮,显示在dialog的最左面。
        .setNeutralButton("Neutral", object : DialogInterface.OnClickListener {
            override fun onClick(dialog: DialogInterface?, which: Int) {
                Toast.makeText(applicationContext, "Neutral", Toast.LENGTH_SHORT).show()
            }
        })
    val dialog = builder.create()
    dialog.show()
}

在这里插入图片描述

2、单选对话框
    private fun showSingleChoiceAlertDialog(){
        val subj = arrayOf("android", "linux", "java", "ios", "c", "html")
        val builder = AlertDialog.Builder(this@AlertDialogActivity)
            .setIcon(R.mipmap.ic_launcher)
            .setTitle("单选对话框")
            // 第二个参数为默认选中项 在这里设为第一项
            .setSingleChoiceItems(subj, 0) { dialog, which ->
            Toast.makeText(this@AlertDialogActivity, "我选择" + subj[which] + "这门课", Toast.LENGTH_SHORT)
                .show()
        }.setPositiveButton("提交") { dialog, which ->
            Toast.makeText(this@AlertDialogActivity, "您已经提交您的选择", Toast.LENGTH_SHORT).show()
        }.setNeutralButton("取消"){
                    dialog, which ->
                Toast.makeText(this@AlertDialogActivity, "您点击了取消按钮", Toast.LENGTH_SHORT).show()
            }
        val dialog = builder.create()
        dialog.show()
    }

在这里插入图片描述

3、多选对话框
    private fun showMultipleChoiceAlertDialog() {
        val subj = arrayOf("android", "linux", "java", "ios", "c")
        val builder = AlertDialog.Builder(this)
            .setIcon(R.mipmap.ic_launcher)
            .setTitle("多选对话框")
            .setMultiChoiceItems(subj, null) { dialog, which, isChecked ->
                if (isChecked) {
                    Toast.makeText(
                        this@AlertDialogActivity,
                        "我喜欢" + subj[which],
                        Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(
                        this@AlertDialogActivity,
                        "我不喜欢" + subj[which],
                        Toast.LENGTH_SHORT).show()
                }
            }.setPositiveButton("提交") { dialog, which ->
            Toast.makeText(this@AlertDialogActivity, "您已经提交您的选择", Toast.LENGTH_SHORT).show()
        }.setNeutralButton("取消") { dialog, which ->
                Toast.makeText(this@AlertDialogActivity, "您关闭了弹窗", Toast.LENGTH_SHORT).show()
            }
        val dialog = builder.create()
        dialog.show()
    }

在这里插入图片描述

4、列表对话框
    /**
     * 列表对话框,内容多了就可滚动。这个dialog感觉没啥用。
     * ps:当单选、多选对话框的内容多了也可滚动。
     * */
    private fun showListAlertDialog() {
        val subj = arrayOf("android", "linux", "java", "ios", "c","kotlin")
        val builder = AlertDialog.Builder(this)
        .setIcon(R.mipmap.ic_launcher)
        .setTitle("列表对话框")
        .setItems(subj) { dialog, which ->
            Toast.makeText(this@AlertDialogActivity, "您选择了" + subj[which], Toast.LENGTH_SHORT).show()
        }
        val dialog = builder.create()
        dialog.show()
    }

在这里插入图片描述

5、自定义对话框

AlertDialog的UI我们不满意时也是可以稍加定制的。

    /**
     * 基于AlertDialog进行自定义对话框
     * 标题、title的UI格式已经被定制过了,我们可以定义其下方区域的ui
     * */
    private fun showCustomAlertDialog() {
        val builder = AlertDialog.Builder(this)
        builder.setIcon(R.mipmap.ic_launcher)
        builder.setTitle("Custom AlertDialog")
        val inflater = LayoutInflater.from(this)
        val v: View = inflater.inflate(R.layout.layout_custom_alert_dialog, null)
        builder.setView(v)
        val dialog = builder.create()
        dialog.show()
    }

在这里插入图片描述

6、小结

可以看出AlertDialog的UI是系统帮我们定制过的:

(1)上方区域:左上角icon、iocn旁边是标题。

(2)下方区域:不同类型的AlertDialog下方区域各自实现。

系统还提供了api可自定义下方区域的UI。

其他对话框

1、DatePickerDialog

系统提供的一个默认的日期选择对话框

/**
   context – the parent context
 
   themeResId – the resource ID of the theme against which to inflate this dialog,or 0to use the 
                parent context's default alert dialog theme
 
   listener – the listener to call when the user sets the date

   year – the initially selected year

   monthOfYear – the initially selected month of the year(0-11 for compatibility with Calendar.MONTH)
 
   dayOfMonth – the initially selected day of month(1-31,depending on month)
 
 */
public DatePickerDialog (@NonNull Context context,
                         @StyleRes int themeResId,
                         @Nullable OnDateSetListener listener,
                         int year,
                         int monthOfYear,
                         int dayOfMonth)
private fun datePickerDialog() {
    DatePickerDialog(this, object : DatePickerDialog.OnDateSetListener {
        override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
            Toast.makeText(applicationContext, "$year-$month-$dayOfMonth", Toast.LENGTH_SHORT)
                .show()
        }

    }, 2023, 3, 15).show()
}

在这里插入图片描述

上面是默认的UI,然而它还有另外一种UI,只需构造中传递一个UI参数AlertDialog.THEME_HOLO_LIGHT控制下即可:

在这里插入图片描述

2、TimePickerDialog

系统提供的一个默认的时间选择对话框

```java
/**
 * context – the parent context
 *
 * themeResId – the resource ID of the theme to apply to this dialog
 *
 * listener – the listener to call when the time is set
 *
 * hourOfDay – the initial hour
 *
 * minute – the initial minute
 *
 * is24HourView – Whether this is a 24 hour view, or AM/PM.
 *
 * */
public TimePickerDialog(Context context, 
                        int themeResId, 
                        OnTimeSetListener listener,
                        int hourOfDay, 
                        int minute, 
                        boolean, 
                        is24HourView)
    private fun timePickDialog() {
        TimePickerDialog(this, object : TimePickerDialog.OnTimeSetListener {
            override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
               // todo
            }
        },22,56,true).show()
    }

在这里插入图片描述

上面是默认的UI,然而它还有另外一种UI,只需构造中传递一个UI参数AlertDialog.THEME_HOLO_LIGHT控制下即可:
在这里插入图片描述

3、ProgressDialog

已经弃用,官方建议使用ProgressBar代替。

4、DialogFragment

DialogFragment本质上是一个Fragment,也就具有Fragment所拥有的生命周期。在使用时,更容易通过生命周期回调来管理弹窗。对于复杂样式的弹窗,使用DialogFragment更加方便和高效。

自定义Dialog

系统提供的AlertDialog还是有一定的局限性的,开发中不一定会满足我们的需求,此时我们就需要自定义Dialog了。

最近在开发购物车流程中看到UI设计了好多弹窗,这个些弹窗有相似点:

  • 底部弹窗
  • 顶部两个角是圆角
  • 各个弹窗各自内容自定义

在这里插入图片描述

接下来就以这个简单的需求来实现下自定义Dialog

1、核心代码
/**
 * Create by SunnyDay /04/23 18:06:24
 */
class BottomDialog @JvmOverloads constructor(
    @UiContext mContext: Context,
    dialogStyle: Int = R.style.BottomDialog,
    @LayoutRes layoutId: Int
) : Dialog(mContext, dialogStyle) {
    init {
        setContentView(layoutId)
        makeDialogBottom()
    }

    private fun makeDialogBottom() {
        window?.apply {
            setGravity(Gravity.BOTTOM)
            attributes.apply {
                width = ViewGroup.LayoutParams.MATCH_PARENT
                height = ViewGroup.LayoutParams.WRAP_CONTENT
            }
        }
    }

    fun <T : View> getViewById(resId: Int): T {
        return findViewById<View>(resId) as T
    }
}
2、BottomDialog#style

稍微处理下dialog的样式

    <!--自定义dialog的样式-->
    <style name="BottomDialog" parent="@style/AlertDialog.AppCompat">
        <!--无边框-->
        <item name="android:windowFrame">@null</item>
        <!--浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--半透明-->
        <item name="android:windowIsTranslucent">false</item>
        <!--无标题-->
        <item name="android:windowNoTitle">true</item>
        <!--提示框背景-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 触摸dialog以外的地方可关闭dialog-->
        <item name="android:windowCloseOnTouchOutside">true</item>
    </style>
3、BottomDialog#bg

白色背景&上面两个角是圆角

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />
    <corners
        android:topLeftRadius="20dp"
        android:topRightRadius="20dp" />
</shape>
4、食用
    private fun showCustomDialog() {
        //注意这里直接使用第三个参数时需要写参数名
        val bottomDialog = BottomDialog(this, layoutId = R.layout.dialog_permission)
        bottomDialog.show()

        bottomDialog.getViewById<View>(R.id.sure).setOnClickListener {
            Toast.makeText(applicationContext,"got permission !",Toast.LENGTH_SHORT).show()
            bottomDialog.dismiss()
        }

        bottomDialog.getViewById<View>(R.id.cancel).setOnClickListener {
            Toast.makeText(applicationContext,"no permission !",Toast.LENGTH_SHORT).show()
            bottomDialog.dismiss()
        }
    }

小结

1、本章能够了解到
  • AlertDialog 基本用法
  • Dialog的关系图
  • 如何自定义dialog
  • @JvmOverloads关键字作用
  • kotlin具名参数注意点
2、感悟

有没有发现一个问题,dialog需要的context我们传递非activity的context(如service的或者Application的)会怎样?dialog深究起来也是一块知识点,以后再总结喽。完事,溜了~

官方文档

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值