如何在安卓中创建自定义对话框?

406
我想创建一个类似下面的自定义对话框:

enter image description here

我尝试了以下几种方法:
  1. 创建了一个AlertDialog.Builder的子类,并使用自定义标题和自定义内容视图,但结果不如预期。

  2. 另一种尝试是创建DialogFragment的子类,并在onCreateDialog中自定义对话框,但结果不如预期。

  3. 然后我尝试使用普通的Dialog类。结果不如预期。

在这三种情况下,当我忽略标题视图时,对话框的大小不如预期,当我使用标题视图时,结果是内容视图周围有一个厚厚的边框(看起来真的很糟糕)。现在我脑海中有两个问题...
  1. 我该如何实现?由于我已经尝试了很多方法,直接回答将更加赞赏。

  2. 在Android应用程序中显示错误或警报对话框的最佳方法是什么?

编辑 Android开发文档建议我们使用DialogFragments或Dialogs来向用户显示错误/警报消息。然而在某一个点上,他们说...

提示:如果你想要一个自定义对话框,你可以代替使用Dialog APIs来显示一个Activity作为对话框。只需创建一个活动并将其主题设置为manifest元素中的Theme.Holo.Dialog即可。

这是什么意思?难道仅为了显示错误消息就使用一个Activity太过于浪费了吗?


仅因为问题的第二部分尚未回答...向用户显示错误/警报消息的最佳方法是什么? - Amit
@sumit-bijwani:我不明白你需要什么,已经有被接受的答案了,你为什么要提供悬赏? - Akhil
3
使用DialogFragment比接受的答案更好。 - Benoit
@Amit 根据图片来看,你想要实现的对话框似乎包含与标准 AlertDialog 相同的元素(标题、内容、按钮栏)。因此,我猜你可以仅通过样式来实现你想要的外观。 - Anderson
要使用Dialog Fragment实现此功能,请参见http://learnzone.info/android-tutorial-custom-alert-dialog-using-dialogfragment/。 - Madhav Bhattarai
21个回答

1
我将发布我正在使用的 Kotlin 代码,它对我来说运行良好。您还可以为对话框按钮设置点击监听器。
这是我的 XML 代码:

layout_custom_alert_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layoutDirection="ltr"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:id="@+id/view6"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:background="@color/colorPrimary" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/view6"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp">


        <TextView
            android:id="@+id/txt_alert_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            tools:text="are you sure?"
            android:textAlignment="center"
            android:textColor="@android:color/black"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <Button
            android:id="@+id/btn_alert_positive"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/textView2"
            android:layout_marginTop="8dp"
            android:background="@android:color/transparent"
            tools:text="yes"
            android:textColor="@color/colorPrimaryDark"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/btn_alert_negative"
            app:layout_constraintTop_toBottomOf="@+id/txt_alert_title" />

        <Button
            android:id="@+id/btn_alert_negative"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:background="@android:color/transparent"
            tools:text="no"
            android:textColor="@color/colorPrimaryDark"
            app:layout_constraintEnd_toStartOf="@+id/btn_alert_positive"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/txt_alert_title" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>

mAlertDialog.kt

class mAlertDialog(context: Context) {

    private val btn_positive : Button
    private val btn_negative : Button
    private val txt_alert_title : TextView
    private val dialog : AlertDialog
    init {
        val view = LayoutInflater.from(context).inflate(R.layout.layout_custom_alert_dialog,null)

        val dialog_builder = AlertDialog.Builder(context)
        dialog_builder.setView(view)

        btn_negative = view.findViewById(R.id.btn_alert_negative)
        btn_positive = view.findViewById(R.id.btn_alert_positive)
        txt_alert_title = view.findViewById(R.id.txt_alert_title)

        dialog = dialog_builder.create() 
    }

    fun show()
    {
        dialog.show()
    }

    fun setPositiveClickListener(listener :onClickListener)
    {
        btn_positive.setOnClickListener { v ->
            listener.onClick(btn_positive)
            dialog.dismiss()
        }
    }

    fun setNegativeClickListener(listener: onClickListener)
    {
        btn_negative.setOnClickListener { v ->
            listener.onClick(btn_negative)
            dialog.dismiss()
        }
    }

    fun setPoitiveButtonText(text : String)
    {
        btn_positive.text = text
    }


    fun setNegativeButtonText(text : String)
    {
        btn_negative.text = text
    }

    fun setAlertTitle(title : String)
    {
        txt_alert_title.text = title
    }
}

点击监听器的接口:

onClickListener.kt

interface onClickListener{
    fun onClick(view : View)
}

示例用法

val dialog = mAlertDialog(context)
                dialog.setNegativeButtonText("no i dont")
                dialog.setPoitiveButtonText("yes is do")
                dialog.setAlertTitle("do you like this alert dialog?")

                dialog.setPositiveClickListener(object : onClickListener {
                    override fun onClick(view: View) {
                        Toast.makeText(context, "yes", Toast.LENGTH_SHORT).show()
                    }
                })

                dialog.setNegativeClickListener(object : onClickListener {
                    override fun onClick(view: View) {
                        Toast.makeText(context, "no", Toast.LENGTH_SHORT).show()
                    }
                })

                dialog.show()

我希望这能帮到你!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接