安卓(kotlin)自定義彈出框

在安卓開發中,咱們常常會遇到這種狀況,就是可愛的UI們設計了一套屬於咱們本身風格的彈出框,爲了彰顯咱們本身的風格,使用自動的dialog固然知足不了咱們的需求,因此仍是得這基礎上寫出咱們本身的提示框,之後UI再變化,咱們也只須要修改樣式就行了。android

1.首先咱們先寫好dialog的樣式app

custom_dialog.xmlide

<?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.ktui

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的背景this

drawable/comment_dialog_bg.xmlspa

<?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.xmlcode

<style name="CustomDialog" parent="android:Theme.Dialog">
        <item name="android:windowBackground">@drawable/comment_dialog_bg</item>
    </style>

5.最後在activity裏定義並調用自定義dialog的方法。xml

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設置爲公共屬性。

效果以下
be902c2e8e6aa2e10cd9c4d4c125814.jpg

相關文章
相關標籤/搜索