Kotlin - Android 中的自定义对话框

问题描述 投票:0回答:9

我想在

Kotlin
中创建一个 custom dialog。我在 Stack Overflow 上查看了有关此主题的问题,但找不到任何有用的信息。我该怎么办?

android kotlin dialog
9个回答
80
投票

您可以使用以下代码来创建自定义对话框。这是我的工作代码。

private fun showDialog(title: String) {
    val dialog = Dialog(activity)
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog.setCancelable(false)
    dialog.setContentView(R.layout.custom_layout)

    val body = dialog.findViewById(R.id.body) as TextView
    body.text = title

    val yesBtn = dialog.findViewById(R.id.yesBtn) as Button
    yesBtn.setOnClickListener {
        dialog.dismiss()
    }

    val noBtn = dialog.findViewById(R.id.noBtn) as Button
    noBtn.setOnClickListener { 
        dialog.dismiss() 
    }

    dialog.show()
}

25
投票

自定义_dialog.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fitsdk_white_rectangle"
android:orientation="vertical">


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="30dp"
        android:layout_marginRight="15dp"
        android:layout_marginBottom="30dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/error_timeout_title"
            android:textColor="@color/black" />

        <TextView
            android:id="@+id/tvBody"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="@string/error_timeout_body"
            android:textColor="@color/black" />

        <Button
            android:id="@+id/btn_yes"
            android:layout_width="100dp"
            android:layout_height="30dp"
            android:background="@android:color/white"
            android:clickable="true"
            android:text="Yes"
            android:textColor="#5DBCD2"
            android:textStyle="bold" />
    </LinearLayout>

</FrameLayout>

自定义对话框类.kt

class CustomDialogClass(context: Context) : Dialog(context) {
    
        init {
            setCancelable(false)
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            requestWindowFeature(Window.FEATURE_NO_TITLE)
            setContentView(R.layout.custom_dialog)
    
        }
}

10
投票

下面是我的解决方案,作为一种“消息框”。 我还没有实现“确定”按钮。单击后,消息框应关闭。

这里是布局元素(*/layout/message_box.xml)

<?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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/message_box_header"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:textAlignment="center"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/message_box_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            android:textSize="20sp" />

    </LinearLayout>
</LinearLayout>

我在 Fragment 类中实现了这个函数。它是用 Kotlin 编写的。

fun showMessageBox(text: String){

    //Inflate the dialog as custom view
    val messageBoxView = LayoutInflater.from(activity).inflate(R.layout.message_box, null)

    //AlertDialogBuilder
    val messageBoxBuilder = AlertDialog.Builder(activity).setView(messageBoxView)

    //setting text values
    messageBoxView.message_box_header.text = "This is message header"
    messageBoxView.message_box_content.text = "This is message content"

    //show dialog
    val  messageBoxInstance = messageBoxBuilder.show()

    //set Listener
    messageBoxView.setOnClickListener(){
        //close dialog
        messageBoxInstance.dismiss()
    }
}

6
投票

您在 kotlin 中的 context 扩展函数上有干净的代码,并将其用于 你所有的代码

fun Context.showDialog(
    title: String,
    description: String,
    titleOfPositiveButton: String? = null,
    titleOfNegativeButton: String? = null,
    positiveButtonFunction: (() -> Unit)? = null,
    negativeButtonFunction: (() -> Unit)? = null
) {
    val dialog = Dialog(this, R.style.Theme_Dialog)
    dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) // if you have blue line on top of your dialog, you need use this code
    dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
    dialog.setCancelable(false)
    dialog.setContentView(R.layout.dialog_custom_layout)
    val dialogTitle = dialog.findViewById(R.id.title) as TextView
    val dialogDescription = dialog.findViewById(R.id.description) as TextView
    val dialogPositiveButton = dialog.findViewById(R.id.positiveButton) as TextView
    val dialogNegativeButton = dialog.findViewById(R.id.negativeButton) as TextView
    dialogTitle.text = title
    dialogDescription.text = description
    titleOfPositiveButton?.let { dialogPositiveButton.text = it } ?: dialogPositiveButton.makeGone()
    titleOfNegativeButton?.let { dialogNegativeButton.text = it } ?: dialogNegativeButton.makeGone()
    dialogPositiveButton.setOnClickListener {
        positiveButtonFunction?.invoke()
        dialog.dismiss()
    }
    dialogNegativeButton.setOnClickListener {
        negativeButtonFunction?.invoke()
        dialog.dismiss()
    }
    dialog.show()
}

这是使用此功能的示例

requireContext().showDialog(
            title = "Your Title",
            description = "Your Description",
            titleOfPositiveButton = "yes",
            titleOfNegativeButton = "No",
            positiveButtonFunction = { // Run codes after click on positive button },
            negativeButtonFunction = { // Run codes after click on negative button }
        )

并且您需要在对话框的设计上保持一致的风格

<style name="Theme_Dialog" parent="android:Theme.Holo.Dialog">
        <item name="android:windowMinWidthMajor">90%</item>
        <item name="android:windowMinWidthMinor">90%</item>
    </style>

3
投票

通过这种方式,您可以使用自定义布局创建自己的对话框。

val dialogBuilder = AlertDialog.Builder(context, R.style.AlertDialogTheme)
    val inflater = this.layoutInflater
    val dialogView = inflater.inflate(R.layout.layout_chat_type_selection, null)
    dialogBuilder.setView(dialogView)
    val radioGroupChat = dialogView.radio_group_chat
    dialogView.radioButton_user_chat.isChecked = true
    dialogBuilder.setPositiveButton(getString(R.string.ok_text), object : DialogInterface.OnClickListener {
        override fun onClick(dialog: DialogInterface, id: Int) {
            when (radioGroupChat.checkedRadioButtonId) {
                R.id.radioButton_user_chat -> {
                    (activity as HomeActivity).replaceFragment(MySkippersFragment.getInstance(isFromChat = true))
                }
                R.id.radioButton_circle_chat -> {
                    (activity as HomeActivity).replaceFragment(PickCircleFragment.getInstance(
                        PickCircleFragment.NEW_CIRCLE_CHAT), true)
                }
            }
        }
    })
    dialogBuilder.setNegativeButton(getString(R.string.cancel_text), object : DialogInterface.OnClickListener {
        override fun onClick(dialog: DialogInterface?, which: Int) {
        }
    })

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

2
投票

工作正常。您还可以按照您想要的方式自定义它。

主课:

class CustomAlertDialogOneButton( activity: Activity?,
private val alertOneButtonClickListener: OnAlertOneButtonClickListener):Dialog(activity!!) {

private var title = ""
private var text = ""
private var dialogId = -1
private var buttonName = ""

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.custom_alert_one_button_dialog)
    setCancelable(false)
    this.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
    viewsClickListenerInit()
}

override fun onStart() {
    initDialog()
    super.onStart()
}

private fun fillFields(title: String, text: String?, dialogId: Int, buttonName: String) {
    clearDialog()
    this.title = title
    this.text = text ?: ""
    this.dialogId = dialogId
    this.buttonName = buttonName
}

private fun clearDialog() {
    title = ""
    text = ""
}

private fun initDialog() {
    if (title.isNotBlank()) {
        tvAlertTitle.text = title
    }

    if (text.isNotBlank()) {
        tvAlertText.text = text
    }

    tvAlertButtonOk.text = buttonName
}

fun show(title: String, text: String?, dialogId: Int = -1, buttonName: String = ResourcesRepository.resources.getString(R.string.ok)) {
    fillFields(title, text, dialogId, buttonName)
    super.show()
}

private fun viewsClickListenerInit() {
    tvAlertButtonOk.setOnClickListener {
        alertOneButtonClickListener.okClickListener(dialogId)
        dismiss()
    }
}}

其 XML: 为其命名 - custom_alert_one_button_dialog.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="280dp"
android:layout_height="145dp"
android:background="@color/colorWhite"
android:orientation="vertical">

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/center_vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5" />

<TextView
    android:id="@+id/tvAlertTitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingStart="24dp"
    android:paddingTop="22dp"
    android:textAlignment="center"
    android:textColor="@color/colorDarkGrey"
    android:textSize="20sp"
    android:textStyle="bold"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/tvAlertText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingStart="24dp"
    android:paddingTop="13dp"
    android:paddingEnd="24dp"
    android:paddingBottom="10dp"
    android:textColor="@color/colorGrey"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tvAlertTitle" />

<TextView
    android:id="@+id/tvAlertButtonOk"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingStart="10dp"
    android:paddingTop="10dp"
    android:paddingEnd="34dp"
    android:paddingBottom="18dp"
    android:text="@string/ok"
    android:textColor="@color/colorDarkGrey"
    android:textSize="14sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

按钮点击监听器接口:

interface OnAlertOneButtonClickListener {

fun okClickListener(dialogId: Int = -1)}

实施:

class SomeActivity : AppCompatActivity(), OnAlertOneButtonClickListener {
****
 private var customDialogOneButton by lazy {
    CustomAlertDialogOneButton(this, this)
 }
****
customDialogOneButton.show(
                title = "some title",
                text = "some text",
                dialogId = some int constant,
                buttonName = "some button name"
            )
****
override fun okClickListener(dialogId: Int) {
    when (dialogId) {
        some int constant -> {
            // call method
        }

    }
}

2
投票

我的自定义对话框 xml 文件:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/dialogWindowBackground">
    
        <TextView
            android:id="@+id/popup_dialog"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16sp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16sp"
            android:layout_marginBottom="10dp"
            android:text="@string/body"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    
        <LinearLayout
            android:id="@+id/linearLayoutOpt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16sp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16sp"
            android:layout_marginBottom="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/popup_dialog">
    
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:orientation="horizontal">
    
    
                <TextView
                    android:id="@+id/no_opt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:gravity="center_vertical"
                    android:paddingLeft="8dp"
                    android:paddingTop="8dp"
                    android:paddingRight="8dp"
                    android:paddingBottom="18dp"
                    android:text="No"
                    android:textAllCaps="false"
                    android:textColor="@color/colorAccent" />
    
                <Space
                    android:layout_width="32sp"
                    android:layout_height="12sp" />
    
    
                <TextView
                    android:id="@+id/yes_opt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:gravity="center_vertical"
                    android:paddingLeft="8dp"
                    android:paddingTop="8dp"
                    android:paddingRight="8dp"
                    android:paddingBottom="18dp"
                    android:text="Yes"
                    android:textAllCaps="false"
                    android:textColor="@color/colorAccent" />
    
            </LinearLayout>
    
        </LinearLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>

我的 Kotlin 代码:

    private fun showDialog() {
    val customDialog = Dialog(requireActivity())
    customDialog.setContentView(R.layout.custom_dialog)
    customDialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
    val yesBtn = customDialog.findViewById(R.id.yes_opt) as TextView
    val noBtn = customDialog.findViewById(R.id.no_opt) as TextView
    yesBtn.setOnClickListener {
        //Do something here
        customDialog.dismiss()
    }
    noBtn.setOnClickListener {
        customDialog.dismiss()
    }
    customDialog.show()
}

0
投票

如果有人想在对话框上显示 2 个按钮(通用解决方案)KOTLIN

   fun createCustomTwoButtonDialog(
    msg: String, context: Context?
    , positiveButtonText: String, negativeButtonText: String,
    isCancellable: Boolean,
    dialogListener: DialogListener
) {
    context?.let { context ->
        val builder =
            AlertDialog.Builder(context)
        builder.setTitle("Your desired title")
        builder.setMessage(msg)
        builder.setCancelable(isCancellable)
        builder.setPositiveButton(positiveButtonText) { dialogInterface: DialogInterface?, i: Int ->
            dialogListener.onPositiveClick()
            dialogInterface?.dismiss()
        }
        builder.setNegativeButton(negativeButtonText)
        { dialogInterface: DialogInterface?, i: Int ->
            dialogListener.onNegativeClick()
            dialogInterface?.dismiss()
        }
        val alertDialog = builder.create()
        alertDialog.show()
    }
}

DialogListener 是具有 2 个方法 onNegativeClick() 和 onPositiveClick() 的接口


0
投票

我创建了这个 Kotlin 类:

class AnimDialog(private val context: Context) {
    private val dialog = Dialog(context)
    fun test(s: String) {
        Log.i("TAG", "test: $s")
    }
init{

    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
    dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
    fun one(headerImage :Int?=null,
        description: String,
            titleOfPositiveButton: String? = null,
            titleOfNegativeButton: String? = null,
            positiveButtonFunction: (() -> Unit)? = null,
            negativeButtonFunction: (() -> Unit)? = null
    ) :Dialog{

        dialog.setCancelable(false)
        dialog.setContentView(R.layout.dialog_one)
        val dialogHeaderImage=dialog.findViewById(R.id.imageHead_dia) as ImageView
        val dialogDescription = dialog.findViewById(R.id.description) as TextView
        val dialogPositiveButton = dialog.findViewById(R.id.positiveButton) as Button
        val dialogNegativeButton = dialog.findViewById(R.id.negativeButton) as Button

        headerImage?.let { dialogHeaderImage.setImageResource(it) }
        dialogHeaderImage.
        startAnimation(
            AnimationUtils.loadAnimation(
                context,
                R.anim.bounce
            )
        )
        dialogDescription.text = description
        titleOfPositiveButton?.let { dialogPositiveButton.text = it } ?: dialogPositiveButton.text
        titleOfNegativeButton?.let { dialogNegativeButton.text = it } ?: dialogNegativeButton.text
        dialogPositiveButton.setOnClickListener {
            positiveButtonFunction?.invoke()
            dialog.dismiss()
        }
        dialogNegativeButton.setOnClickListener {
            negativeButtonFunction?.invoke()
            dialog.dismiss()
        }


return dialog

    }

您必须定义的位置:

1- 布局

<dialog_one>
包括正btn、负btn、图像视图、文本视图

2- 动画

<bounce>
如果您想将动画添加到标题图像

现在处于活动

 val animDialog = AnimDialog(this)


        animDialog.one(
            headerImage = android.R.drawable.ic_delete,
            description = "Sometimes we looking for new dialog to fill better \n ",
            titleOfPositiveButton = "Accept it",
            titleOfNegativeButton = "Not now",
            positiveButtonFunction = {
                animDialog.test("OK")
            },
            negativeButtonFunction = {
                animDialog.test("NO")
            }).show()

© www.soinside.com 2019 - 2024. All rights reserved.