在安卓开发中,我们经常会遇到这种情况,就是可爱的UI们设计了一套属于我们自己风格的弹出框,为了彰显我们自己的风格,使用自动的dialog当然满足不了我们的需求,所以还是得这基础上写出我们自己的提示框,以后UI再变化,我们也只需要修改样式就好了。
1.首先我们先写好dialog的样式
custom_dialog.xml
2.然后定义一个CustomDialog继承Dialog,在这里定义我们自己要调用的方法等。
CustomDialog.kt
package com.xindong.rocket
import android.app.Dialog
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
class CustomDialog : Dialog {
constructor(context: Context) : super(context) {}
constructor(context: Context, theme: Int) : super(context, theme) {}
class Builder(context: Context) {
private var title: String? = null
private var message: String? = null
private var contentView: View? = null
private var positiveButtonText: String? = null
private var negativeButtonText: String? = null
private var singleButtonText: String? = null
private var positiveButtonClickListener: View.OnClickListener? = null
private var negativeButtonClickListener: View.OnClickListener? = null
private var singleButtonClickListener: View.OnClickListener? = null
private val layout: View
private val dialog: CustomDialog = CustomDialog(context, R.style.CustomDialog)
init {
//这里传入自定义的style,直接影响此Dialog的显示效果。style具体实现见style.xml
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layout = inflater.inflate(R.layout.custom_dialog, null)
dialog.addContentView(layout, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
}
fun setTitle(title: String): Builder{
this.title = title
return this
}
fun setMessage(message: String): Builder {
this.message = message
return this
}
fun setContentView(v: View): Builder {
this.contentView = v
return this
}
fun setPositiveButton(positiveButtonText: String, listener: View.OnClickListener): Builder {
this.positiveButtonText = positiveButtonText
this.positiveButtonClickListener = listener
return this
}
fun setNegativeButton(negativeButtonText: String, listener: View.OnClickListener): Builder {
this.negativeButtonText = negativeButtonText
this.negativeButtonClickListener = listener
return this
}
fun setSingleButton(singleButtonText: String, listener: View.OnClickListener): Builder {
this.singleButtonText = singleButtonText
this.singleButtonClickListener = listener
return this
}
/**
* 创建单按钮对话框
* @return
*/
fun createSingleButtonDialog(): CustomDialog {
showSingleButton()
layout.findViewById(R.id.singleBtn).setOnClickListener(singleButtonClickListener)
//如果传入的按钮文字为空,则使用默认的“知道了”
if (singleButtonText != null) {
(layout.findViewById(R.id.singleBtn) as TextView).text = singleButtonText
} else {
(layout.findViewById(R.id.singleBtn) as TextView).text = "知道了"
}
create()
return dialog
}
/**
* 创建双按钮对话框
* @return
*/
fun createTwoButtonDialog(): CustomDialog {
showTwoButton()
layout.findViewById(R.id.positiveBtn).setOnClickListener(positiveButtonClickListener)
layout.findViewById(R.id.negativeBtn).setOnClickListener(negativeButtonClickListener)
//如果传入的按钮文字为空,则使用默认的“确定”和“取消”
if (positiveButtonText != null) {
(layout.findViewById(R.id.positiveBtn) as TextView).text = positiveButtonText
} else {
(layout.findViewById(R.id.positiveBtn) as TextView).text = "确定"
}
if (negativeButtonText != null) {
(layout.findViewById(R.id.negativeBtn) as TextView).text = negativeButtonText
} else {
(layout.findViewById(R.id.negativeBtn) as TextView).text = "取消"
}
create()
return dialog
}
/**
* 单按钮对话框和双按钮对话框的公共部分在这里设置
*/
private fun create() {
if (message != null) { //设置提示内容
(layout.findViewById(R.id.message) as TextView).text = message
} else if (contentView != null) { //如果使用Builder的setContentview()方法传入了布局,则使用传入的布局
(layout.findViewById(R.id.content) as LinearLayout).removeAllViews()
(layout.findViewById(R.id.content) as LinearLayout)
.addView(contentView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
}
if(title!=null && title!!.isNotEmpty()){
(layout.findViewById(R.id.title) as TextView).text = title
showTitle()
}
dialog.setContentView(layout)
dialog.setCancelable(true) //用户可以点击手机Back键取消对话框显示
dialog.setCanceledOnTouchOutside(false) //用户不能通过点击对话框之外的地方取消对话框显示
}
/**
* 显示双按钮布局,隐藏单按钮
*/
private fun showTwoButton() {
layout.findViewById(R.id.singleButtonLayout).visibility = View.GONE
layout.findViewById(R.id.twoButtonLayout).visibility = View.VISIBLE
}
/**
* 显示单按钮布局,隐藏双按钮
*/
private fun showSingleButton() {
layout.findViewById(R.id.singleButtonLayout).visibility = View.VISIBLE
layout.findViewById(R.id.twoButtonLayout).visibility = View.GONE
}
private fun showTitle() {
layout.findViewById(R.id.title).visibility = View.VISIBLE
}
}
}
3.设置dialog的背景
drawable/comment_dialog_bg.xml
4.将上面写好的dialog背景设置给一个style
style.xml
5.最后在activity里定义并调用自定义dialog的方法。
MainActivty.kt
private var builderForCustom: CustomDialog.Builder? = null
private var mDialog: CustomDialog? = null
然后在onCreate里
builderForCustom = CustomDialog.Builder(this)
定义方法
private fun showSingleButtonDialog(title: String, alertText: String, btnText: String, onClickListener:View.OnClickListener) {
mDialog = builderForCustom!!.setTitle(title)
.setMessage(alertText)
.setSingleButton(btnText, onClickListener)
.createSingleButtonDialog()
mDialog!!.show()
}
private fun showTwoButtonDialog(title: String, alertText: String, confirmText: String, cancelText: String, conFirmListener: View.OnClickListener, cancelListener: View.OnClickListener) {
mDialog = builderForCustom!!.setTitle(title)
.setMessage(alertText)
.setPositiveButton(confirmText, conFirmListener)
.setNegativeButton(cancelText, cancelListener)
.createTwoButtonDialog()
mDialog!!.show()
}
调用方法
showTwoButtonDialog("", "这是自定义弹出框","确定", "取消", View.OnClickListener {
// 操作
mDialog!!.dismiss()
},View.OnClickListener {
// 操作
mDialog!!.dismiss()
})
调用单个按钮的方法也是同样的方式。
如果是在fragment调用activity里定义的弹出框方法,则可以单独定义一个关闭弹出框的方法,或者将mDialog设置为公共属性。
效果如下