【问题标题】:Kotlin - custom dialog in AndroidKotlin - Android 中的自定义对话框
【发布时间】:2019-02-04 04:53:01
【问题描述】:

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

【问题讨论】:

  • 创建自定义对话框在 java 和 kotlin 之间没有任何严重的区别。所以只是谷歌为 android 创建自定义对话框 - 它
  • 嗨,发布你的代码
  • 如果您找到用 java 编写的自定义对话框的代码,android studio 会将其转换为 kotlin
  • 要学习和提高对 Kotlin 的理解,可以用 Java 编写代码,然后convert it to Kotlin。另请参阅 Android StudioCode 菜单中的 Convert Java File to Kotlin File 命令。

标签: android kotlin dialog


【解决方案1】:

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

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】:

您可以将以下代码用于自定义对话框。这是我的工作代码。

 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
    val noBtn = dialog.findViewById(R.id.noBtn) as TextView
    yesBtn.setOnClickListener {
        dialog.dismiss()
    }
    noBtn.setOnClickListener { dialog.dismiss() }
    dialog.show()

}

【讨论】:

  • 如果这个也有一些 xml 就好了 :)
  • 虽然很基本,但答案很好。
  • activity 应该是什么?这里说的是未解决的参考
  • @RichardBarraclough 我相信应该是上下文,所以可以使用this
  • @RichardBarraclough 您需要为活动或片段引用传递上下文。谢谢 Shantanu Dharmavat
【解决方案3】:

custom_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>

CustomDialogClass.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)
    
        }
}

【讨论】:

  • 如何从另一个活动/片段中调用它
  • 嗨,请添加一个示例,如何在主要活动中调用这个有趣的答案
  • 能否请您添加关于如何从 Activity/Fragment 调用它的评论,因为当通过 Kotlin 完成时,onCreate() 不会被调用,导致视图出现空指针异常
  • 您可以这样称呼它:CustomDialogClass(this).show() 从您需要调用它的任何地方。 this 指上下文。您可以使用show(),因为 CustomDialogClass 继承自 Dialog。
【解决方案4】:

如果有人想在对话框上显示 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 是两个方法 onNegativeClick() 和 onPositiveClick() 的接口

【讨论】:

    【解决方案5】:

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

    这里是布局元素(*/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】:

      工作正常。您还可以按照自己的方式对其进行自定义。

      主类:

      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
              }
      
          }
      }
      

      【讨论】:

        【解决方案7】:

        我的自定义对话框 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()
        }
        

        【讨论】:

          【解决方案8】:

          你在 kotlin 的上下文扩展函数上有一个干净的代码,并在一个 你所有的代码

          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>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多