使用 Kotlin 创建 Android 警报对话框

在本教程中,我们将讨论警告对话框并在我们的Android应用程序中使用Kotlin实现它们。

警告对话框

警告对话框是弹出在屏幕上的窗口。它们通常显示一些信息并询问用户采取行动。构建警告对话框的三个核心组件有:

  • 标题文本
  • 消息文本
  • 按钮 – 有三种类型的按钮:积极、消极和中性

要创建AlertDialog,我们使用AlertDialog.Builder内部类。

val alertDialogBuilder = AlertDialog.Builder(this)

我们在构造函数中传递上下文。可选地,我们可以传递另一个参数,即警告对话框样式。

警告对话框方法

一些可用于AlertDialog的方法有:

  • setTitle
  • setMessage
  • setIcon
  • setCustomTitle – 在这里,您可以传递一个自定义视图,该视图将放置在警告对话框中标题部分的位置。
  • setPositiveButton – 我们在这里传递字符串名称以及按钮点击回调方法。
  • setView – 用于在警告对话框内部添加自定义视图。
  • setList – 用于设置字符串数组,以列表形式显示。
  • setMultiChoiceList – 再次可以设置一个数组,但这次可以通过复选框从列表中选择多个项目。
  • setPositiveButtonIcon – 在按钮旁边设置一个图标
  • show() – 用于显示AlertDialog
  • setDismissListener – 在其中,您可以设置当警告对话框被解除时触发的逻辑。
  • setShowListener – 设置当警告对话框被解除时触发的逻辑。
  • setCancelable – 需要一个布尔值。默认情况下,所有警告对话框都可以在按钮点击或触摸外部时取消。如果将此方法设置为false,则需要使用dialog.cancel()方法显式取消对话框。

警告对话框 Kotlin 代码

要在您的Android Studio项目中使用AlertDialog,请导入以下类。

import android.support.v7.app.AlertDialog;

以下 Kotlin 代码用于创建一个简单的警告对话框。

val builder = AlertDialog.Builder(this)
builder.setTitle("Androidly Alert")
builder.setMessage("We have a message")
//builder.setPositiveButton("OK", DialogInterface.OnClickListener(function = x))

builder.setPositiveButton(android.R.string.yes) { dialog, which ->
    Toast.makeText(applicationContext,
            android.R.string.yes, Toast.LENGTH_SHORT).show()
}
        
builder.setNegativeButton(android.R.string.no) { dialog, which ->
    Toast.makeText(applicationContext,
            android.R.string.no, Toast.LENGTH_SHORT).show()
}

builder.setNeutralButton("Maybe") { dialog, which ->
    Toast.makeText(applicationContext,
            "Maybe", Toast.LENGTH_SHORT).show()
}
builder.show()

builder.show()在屏幕上显示警报对话框。在setPositiveButton函数内部,我们传递按钮文本以及一个 Kotlin 函数,当单击该按钮时触发该函数。该函数是DialogInterface.OnClickListener()接口的一部分。函数类型是(DialogInterface, Int) -> Unit。DialogInterface 是对话框的一个实例,而 Int 是单击的按钮的 id。在上述代码中,我们将此函数表示为Higher Order Kotlin functiondialogwhich 分别表示两个参数。如果不使用参数,我们可以通过传递 _ 来改进函数。这些函数看起来像这样:

builder.setPositiveButton(android.R.string.yes) { _,_ ->
            Toast.makeText(applicationContext,
                    android.R.string.yes, Toast.LENGTH_SHORT).show()
        }

另外,我们还可以通过 AlertDialog 类的实例来显示对话框。用以下方式替换 builder.show()

val alertDialog = builder.create()
alertDialog.show()

我们也可以将按钮点击监听器函数分别定义为高阶函数。

val positiveButtonClick = { dialog: DialogInterface, which: Int ->
    Toast.makeText(applicationContext,
            android.R.string.no, Toast.LENGTH_SHORT).show()
}

现在,在setPositiveButton的 Kotlin 函数内设置这个val属性:

builder.setPositiveButton("OK", DialogInterface.OnClickListener(function = positiveButtonClick))
//or
builder.setPositiveButton(android.R.string.yes, positiveButtonClick)

后一种方法使代码看起来更加简洁。以下是我们的 Activity 类的屏幕截图,应用了上述函数以用于每个按钮。

如果您不打算在按钮单击时执行任何操作,可以传递 null。

Kotlin 仍然有更多的能力来提高上述代码的可读性。

简单的警报对话框 Kotlin 代码

使用 with 函数,我们可以提高 Kotlin 代码的可读性,以创建警报对话框。

fun basicAlert(view: View){

        val builder = AlertDialog.Builder(this)
        
        with(builder)
        {
            setTitle("Androidly Alert")
            setMessage("We have a message")
            setPositiveButton("OK", DialogInterface.OnClickListener(function = positiveButtonClick))
            setNegativeButton(android.R.string.no, negativeButtonClick)
            setNeutralButton("Maybe", neutralButtonClick)
            show()    
        }
        
        
    }

在下一部分,我们将创建我们的 Android 应用程序,在其中实现警报对话框的以下功能。

  • 简单的警报对话框
  • 带有图标和按钮自定义的警报对话框
  • 带有列表的警报对话框
  • 带有多选列表的警报对话框
  • 带有样式的警报对话框
  • 带有自定义样式的警报对话框
  • 带有编辑框的警报对话框

Android Studio 项目结构

1. XML 布局代码

下面是 activity_main.xml 布局的代码。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnBasicAlert"
        android:layout_width="wrap_content"
        android:onClick="basicAlert"
        android:layout_height="wrap_content"
        android:text="BASIC ALERT DIALOG" />


    <Button
        android:id="@+id/btnAlertWithIconsAndCustomize"
        android:layout_width="wrap_content"
        android:onClick="withIconAndCustomise"
        android:layout_height="wrap_content"
        android:text="WITH ICON AND CUSTOMIZATION" />

    <Button
        android:id="@+id/btnAlertWithItems"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withItems"
        android:text="WITH ITEMS" />

    <Button
        android:id="@+id/btnAlertWithMultiChoiceList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withMultiChoiceList"
        android:text="WITH MULTI CHOICE LIST" />

    <Button
        android:id="@+id/btnAlertWithStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withStyle"
        android:text="WITH STYLE" />


    <Button
        android:id="@+id/btnAlertWithCustomStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withCustomStyle"
        android:text="WITH CUSTOM STYLE" />

    <Button
        android:id="@+id/btnAlertWithButtonCentered"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withButtonCentered"
        android:text="WITH BUTTON CENTERED" />

    <Button
        android:id="@+id/btnAlertWithEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="withEditText"
        android:text="WITH EDIT TEXT" />


</LinearLayout>

对于每个按钮,我们设置了一个带有函数名称的 android:onClick 属性。这些 Kotlin 函数将在 MainActivity.kt 类中触发。我们将逐个讨论它们。

2. Kotlin主活动代码

我们已经创建了上面的第一个警告对话框。现在让我们看看MainActivity.kt是什么样子的。

package net.androidly.androidlyalertdialog

import android.content.DialogInterface
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.view.View
import android.widget.Toast

class MainActivity : AppCompatActivity() {

    val positiveButtonClick = { dialog: DialogInterface, which: Int ->
        Toast.makeText(applicationContext,
                android.R.string.yes, Toast.LENGTH_SHORT).show()
    }
    val negativeButtonClick = { dialog: DialogInterface, which: Int ->
        Toast.makeText(applicationContext,
                android.R.string.no, Toast.LENGTH_SHORT).show()
    }
    val neutralButtonClick = { dialog: DialogInterface, which: Int ->
        Toast.makeText(applicationContext,
                "Maybe", Toast.LENGTH_SHORT).show()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun basicAlert(view: View){

        val builder = AlertDialog.Builder(this)

        with(builder)
        {
            setTitle("Androidly Alert")
            setMessage("We have a message")
            setPositiveButton("OK", DialogInterface.OnClickListener(function = positiveButtonClick))
            setNegativeButton(android.R.string.no, negativeButtonClick)
            setNeutralButton("Maybe", neutralButtonClick)
            show()
        }


    }
}

3. 带图标和自定义的警告对话框

val builder = AlertDialog.Builder(this)
        with(builder) {
            setTitle("Icon and Button Color")
            setMessage("We have a message")
            setPositiveButton("OK", null)
            setNegativeButton("CANCEL", null)
            setNeutralButton("NEUTRAL", null)
            setPositiveButtonIcon(resources.getDrawable(android.R.drawable.ic_menu_call, theme))
            setIcon(resources.getDrawable(android.R.drawable.ic_dialog_alert, theme))
        }
        val alertDialog = builder.create()
        alertDialog.show()

        val button = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)
        with(button) {
            setBackgroundColor(Color.BLACK)
            setPadding(0, 0, 20, 0)
            setTextColor(Color.WHITE)
        }

通过使用getButton,我们可以通过设置它们的相应常量来检索任何按钮。一旦检索到按钮,我们可以像上面那样自定义它。

4. 带有项目的警告对话框

fun withItems(view: View) {

        val items = arrayOf("Red", "Orange", "Yellow", "Blue")
        val builder = AlertDialog.Builder(this)
        with(builder)
        {
            setTitle("List of Items")
            setItems(items) { dialog, which ->
                Toast.makeText(applicationContext, items[which] + " is clicked", Toast.LENGTH_SHORT).show()
            }

            setPositiveButton("OK", positiveButtonClick)
            show()
        }
    }

在setItems中,我们传递Kotlin数组。which参数表示在列表中点击的元素的索引。

5. 带有多选列表的警告对话框

fun withMultiChoiceList(view: View) {

        val items = arrayOf("Microsoft", "Apple", "Amazon", "Google")
        val selectedList = ArrayList<Int>()
        val builder = AlertDialog.Builder(this)

        builder.setTitle("This is list choice dialog box")
        builder.setMultiChoiceItems(items, null
        ) { dialog, which, isChecked ->
            if (isChecked) {
                selectedList.add(which)
            } else if (selectedList.contains(which)) {
                selectedList.remove(Integer.valueOf(which))
            }
        }

        builder.setPositiveButton("DONE") { dialogInterface, i ->
            val selectedStrings = ArrayList<string>()

            for (j in selectedList.indices) {
                selectedStrings.add(items[selectedList[j]])
            }

            Toast.makeText(applicationContext, "Items selected are: " + Arrays.toString(selectedStrings.toTypedArray()), Toast.LENGTH_SHORT).show()
        }

        builder.show()

    }

在上面的代码中,我们将选择保存在整数数组列表中,然后再次检索它们以在 Toast 消息中显示。

6. 具有样式的警报对话框

fun withStyle(view: View) {

        val builder = AlertDialog.Builder(ContextThemeWrapper(this, android.R.style.Holo_SegmentedButton))

        with(builder)
        {
            setTitle("Androidly Alert")
            setMessage("We have a message")
            setPositiveButton("OK", DialogInterface.OnClickListener(function = positiveButtonClick))
            setNegativeButton(android.R.string.no, negativeButtonClick)
            setNeutralButton("Maybe", neutralButtonClick)
            show()
        }
    }

如果不使用 ContextThemeWrapper,则警报对话框将显示在全屏上。

7. 具有自定义样式的警报对话框

在 styles.xml 文件中添加以下代码:

<style name="AlertDialogCustom" parent="@android:style/Theme.Material.Dialog">
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textStyle">bold</item>
        <item name="android:headerDividersEnabled">true</item>
        <item name="android:background">@android:color/holo_blue_dark</item>
    </style>

以下是 Kotlin 函数:

fun withCustomStyle(view: View) {

        val builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.AlertDialogCustom))

        with(builder)
        {
            setTitle("Androidly Alert")
            setMessage("We have a message")
            setPositiveButton("OK", DialogInterface.OnClickListener(function = positiveButtonClick))
            setNegativeButton(android.R.string.no, negativeButtonClick)
            setNeutralButton("Maybe", neutralButtonClick)
            show()
        }

    }

8. 具有按钮居中的警报对话框

fun withButtonCentered(view: View) {

        val alertDialog = AlertDialog.Builder(this).create()
        alertDialog.setTitle("Title")
        alertDialog.setMessage("Message")

        alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes"
        ) { dialog, which -> dialog.dismiss() }

        alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No"
        ) { dialog, which -> dialog.dismiss() }
        alertDialog.show()

        val btnPositive = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
        val btnNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE)

        val layoutParams = btnPositive.layoutParams as LinearLayout.LayoutParams
        layoutParams.weight = 10f
        btnPositive.layoutParams = layoutParams
        btnNegative.layoutParams = layoutParams
    }

9. 带编辑文本的警报对话框

自定义布局 alert_dialog_with_edittext.xml 的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter the text here"/>

</LinearLayout>
fun withEditText(view: View) {
        val builder = AlertDialog.Builder(this)
        val inflater = layoutInflater
        builder.setTitle("With EditText")
        val dialogLayout = inflater.inflate(R.layout.alert_dialog_with_edittext, null)
        val editText  = dialogLayout.findViewById<EditText>(R.id.editText)
        builder.setView(dialogLayout)
        builder.setPositiveButton("OK") { dialogInterface, i -> Toast.makeText(applicationContext, "EditText is " + editText.text.toString(), Toast.LENGTH_SHORT).show() }
        builder.show()
    }

以下是上述应用程序的输出:

下载 Android Studio 项目:AndroidlyAlertDialog

Source:
https://www.digitalocean.com/community/tutorials/android-alert-dialog-using-kotlin