在安卓开发中,我们经常会遇到这种情况,就是可爱的UI们设计了一套属于我们自己风格的弹出框,为了彰显我们自己的风格,使用自动的dialog当然满足不了我们的需求,所以还是得这基础上写出我们自己的提示框,以后UI再变化,我们也只需要修改样式就好了。
1.首先我们先写好dialog的样式
custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:paddingRight="24dp"
android:paddingLeft="24dp"
android:paddingTop="21dp"
android:paddingBottom="21dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#deffffff"
android:letterSpacing="0.03"
android:lineSpacingExtra="8sp"
android:text="提示"
android:layout_marginTop="6dp"
android:layout_marginBottom="15dp"
android:visibility="gone"/>
<TextView
android:id="@+id/message"
android:layout_width="256dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#99ffffff"
android:letterSpacing="0.02"
android:lineSpacingExtra="6sp"
android:text="这是自定义弹出框"
/>
<RelativeLayout
android:id="@+id/twoButtonLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="31dp">
<TextView
android:id="@+id/negativeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#138ef0"
android:letterSpacing="0.09"
android:lineSpacingExtra="2sp"
android:text="取消"
android:layout_alignParentRight="true"
android:layout_marginRight="89dp"
android:padding="10dp"
android:focusableInTouchMode="false"
/>
<TextView
android:id="@+id/positiveBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#138ef0"
android:letterSpacing="0.09"
android:lineSpacingExtra="2sp"
android:text="满意"
android:layout_alignParentRight="true"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="5dp"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/singleButtonLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="41dp">
<TextView
android:id="@+id/singleBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#138ef0"
android:letterSpacing="0.09"
android:lineSpacingExtra="2sp"
android:text="确定"
android:layout_alignParentRight="true"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="5dp"
/>
</RelativeLayout>
</LinearLayout>
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<View>(R.id.singleBtn).setOnClickListener(singleButtonClickListener)
//如果传入的按钮文字为空,则使用默认的“知道了”
if (singleButtonText != null) {
(layout.findViewById<View>(R.id.singleBtn) as TextView).text = singleButtonText
} else {
(layout.findViewById<View>(R.id.singleBtn) as TextView).text = "知道了"
}
create()
return dialog
}
/**
* 创建双按钮对话框
* @return
*/
fun createTwoButtonDialog(): CustomDialog {
showTwoButton()
layout.findViewById<View>(R.id.positiveBtn).setOnClickListener(positiveButtonClickListener)
layout.findViewById<View>(R.id.negativeBtn).setOnClickListener(negativeButtonClickListener)
//如果传入的按钮文字为空,则使用默认的“确定”和“取消”
if (positiveButtonText != null) {
(layout.findViewById<View>(R.id.positiveBtn) as TextView).text = positiveButtonText
} else {
(layout.findViewById<View>(R.id.positiveBtn) as TextView).text = "确定"
}
if (negativeButtonText != null) {
(layout.findViewById<View>(R.id.negativeBtn) as TextView).text = negativeButtonText
} else {
(layout.findViewById<View>(R.id.negativeBtn) as TextView).text = "取消"
}
create()
return dialog
}
/**
* 单按钮对话框和双按钮对话框的公共部分在这里设置
*/
private fun create() {
if (message != null) { //设置提示内容
(layout.findViewById<View>(R.id.message) as TextView).text = message
} else if (contentView != null) { //如果使用Builder的setContentview()方法传入了布局,则使用传入的布局
(layout.findViewById<View>(R.id.content) as LinearLayout).removeAllViews()
(layout.findViewById<View>(R.id.content) as LinearLayout)
.addView(contentView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
}
if(title!=null && title!!.isNotEmpty()){
(layout.findViewById<View>(R.id.title) as TextView).text = title
showTitle()
}
dialog.setContentView(layout)
dialog.setCancelable(true) //用户可以点击手机Back键取消对话框显示
dialog.setCanceledOnTouchOutside(false) //用户不能通过点击对话框之外的地方取消对话框显示
}
/**
* 显示双按钮布局,隐藏单按钮
*/
private fun showTwoButton() {
layout.findViewById<View>(R.id.singleButtonLayout).visibility = View.GONE
layout.findViewById<View>(R.id.twoButtonLayout).visibility = View.VISIBLE
}
/**
* 显示单按钮布局,隐藏双按钮
*/
private fun showSingleButton() {
layout.findViewById<View>(R.id.singleButtonLayout).visibility = View.VISIBLE
layout.findViewById<View>(R.id.twoButtonLayout).visibility = View.GONE
}
private fun showTitle() {
layout.findViewById<View>(R.id.title).visibility = View.VISIBLE
}
}
}
3.设置dialog的背景
drawable/comment_dialog_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp"/>
<solid android:color="#282a34"/>
</shape>
4.将上面写好的dialog背景设置给一个style
style.xml
<style name="CustomDialog" parent="android:Theme.Dialog">
<item name="android:windowBackground">@drawable/comment_dialog_bg</item>
</style>
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设置为公共属性。
效果如下
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。