Detailed explanation of kotlin version of custom dialog box with rounded corners

First take a look at the renderings as follows:

Insert picture description here

Point

Insert picture description here

1. Background introduction

I have encountered a demand for a small package on the overseas shelves, and the effect diagram has been given above. In fact, it is also a simple dialog box. It's just a small requirement:

1. With rounded corners
2. Background image can be dynamically replaced
3. Text can be dynamically replaced
4. Button rounded corners, text dynamic replacement, background color dynamic replacement.

I asked the thief to be simple, thinking that every packet should use this dialog box, so the idea came: I just learned kt and customized the view when I paddled myself some time ago. I also wondered if I could make an aar myself like using a third-party library? Wouldn't it be happy to move bricks in the future? As a fresh graduate, you need to do more, think more, and do a good job! Here is a simple one. The focus is on summarizing the gains. . .

Second, the detailed steps of custom dialog box

1. Ideas

Anyone who knows about custom views knows that customizing new views is sometimes more complicated, and many of them need to be handled by us, such as processing wrap_content, adding padding to the view, and so on. Fortunately, our custom dialog is relatively simple. Just expand on the original view.

(1) Create a class to inherit dialog

(2) Load the layout

(3) Add style

(4) Expose the interface

2. Simple implementation

(1) Create a class to inherit dialog

There's not much to say about this one, it came out three times. . .

/**
 * Created by sunnyDay on 2019/8/22 19:33
 */
class SubscriptionDialog : Dialog {
    
    
}

(2) Load the layout

Loading the layout is actually converting the xml layout file into a view and then displaying it.
There are two conventional methods:
1. View's inflate method
2. LayoutInflater's inflate method (there is a pit when customizing the dialog)
In fact, the setContentView method provided in the dialog class is also the layout converted to view (there is a pit when customizing the dialog)

(3) Add style

The style is similar to the theme of the activity. Beautify the dialog. . .


    <!--自定义对话框的样式-->
    <style name="SubscriptionDialog" parent="@style/AlertDialog.AppCompat">
        <!--边框-->
        <item name="android:windowFrame">@null</item>
        <!--是否浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--半透明-->
        <item name="android:windowIsTranslucent">false</item>
        <!--无标题-->
        <item name="android:windowNoTitle">true</item>
        <!--提示框背景-->
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

(4) Expose the interface

Just provide some methods, such as dialog button event, title content modification. . .

(5) Source code

/**
 * Created by sunnyDay on 2019/8/22 19:33
 */
class SubscriptionDialog : Dialog {
    
    

    private var mOnContinueClickListener: OnContinueClickListener? = null

    /**
     *  use default dialog style
     * */
    constructor(context: Context) : super(context, R.style.SubscriptionDialog) {
    
    
        setContentView(R.layout.dialog_simple)
    }

    /**
     *  user give a custom dialog style
     * */
    constructor(context: Context, dialogStyle: Int) : super(context, dialogStyle) {
    
    
        setContentView(R.layout.dialog_simple)
    }

    /**
     * set image of dialog
     * */
    fun setImage(img: Int): SubscriptionDialog {
    
    
//        when (img) {
    
    
//            img is Int -> iv_img.setImageResource(img as Int)
//            img is Drawable -> iv_img.setImageDrawable(img as Drawable)
//            img is Bitmap -> iv_img.setImageBitmap(img as Bitmap)
//        }
        iv_img.setImageResource(img)
        return this
    }

    /**
     * set the content of dialog
     * */
    fun setContentText(content: String): SubscriptionDialog {
    
    
        tv_content.text = content
        return this
    }

    /**
     * set the content of dialog
     * */
    fun setContentTextColor(contextTextColor: Int): SubscriptionDialog {
    
    
        tv_content.setTextColor(contextTextColor)
        return this
    }

    /**
     * set text of button
     * */
    fun setButtonText(btnText: CharSequence): SubscriptionDialog {
    
    
        bt_button.text = btnText
        return this
    }

    /**
     * set color of button text
     * */
    fun setButtonTextColor(textColor: Int): SubscriptionDialog {
    
    
        bt_button.setTextColor(textColor)
        return this
    }

    /**
     * set color of button bg
     * */
    fun setButtonBackgroundColor(btnBgColor: Int): SubscriptionDialog {
    
    
        bt_button.setBackgroundColor(btnBgColor)
        return this
    }

    /**
     * onClickListener of dialog
     * */
    fun setOnContinueClickListener(onContinueClickListener: OnContinueClickListener?): SubscriptionDialog {
    
    
        mOnContinueClickListener = onContinueClickListener
        onButtonClick()
        return this
    }

    /**
     * show dialog
     * */
    fun showDialog() {
    
    
        this.show()
    }

    /**
     * close dialog
     * */
    fun dismissDialog() {
    
    
        this.dismiss()
    }

    private fun onButtonClick() {
    
    
        bt_button.setOnClickListener {
    
    
            mOnContinueClickListener?.onClick()
                ?: throw Exception("onContinueClickListener is null,please give a non-value.")
        }
    }

    interface OnContinueClickListener {
    
    
        fun onClick()
    }
}

Three, package as aar

1. Understand

1. In fact, our projects are divided into: Android project, Android library, java library.
2. Why package aar? Difference from jar package:

The inner step of the jar package only contains the class file and the manifest file. The
aar file contains all resource files, including class and res resource files. Convenient for us to use res
files

2. Packing

(1) The Android library directly operates as follows

Insert picture description here

(2) Android project

Need to become an Android library and package as above

Change steps

Remove useless code:
1. The manifest only retains the application node and its attributes.
2. App.build is removed as follows:

Insert picture description here

Then pack it

Insert picture description here

3. Use

(1) Copy the aar package to the lib of your project

(2) Add kotlin support and aar introduction (our dialog is packaged in kotlin)

//1、工程的build.grdle添加:

buildscript {
    
    
    ext.kotlin_version = '1.3.21' // kt 版本
    repositories {
    
    
        google()
        jcenter()
        
    }
    dependencies {
    
    
        classpath 'com.android.tools.build:gradle:3.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//kt插件
       
    }
}

// 2、项目的build.gradle 添加:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

// 3、引入aar:

 repositories {
    
    
   flatDir {
    
    
     dirs 'libs' 
   }

 }

 dependencies {
    
    

   implementation(name: 'SubscriptionDialog_1.0.1', ext: 'aar') //必须引入
   implementation 'com.android.support:design:28.0.0'//必须引入,自定义dialog有使用
 }

4. Simple to use
  val dialog = SubscriptionDialog(this)
        dialog
            .setImage(R.drawable.peiqi)//背景图
            .setContentText("hello custom dialog 、hello custom dialog 、hello custom dialog ")//内容
            .setContentTextColor(Color.RED)//内容的字体颜色
            .setButtonText("sunny")//按钮字体
            .setButtonTextColor(Color.BLACK) // 按钮字体颜色
            .setButtonBackgroundColor(Color.parseColor("#FFD81B60"))
            .setOnContinueClickListener(object : SubscriptionDialog.OnContinueClickListener {
    
    
                override fun onClick() {
    
    
                    Toast.makeText(applicationContext, "simple dialog", Toast.LENGTH_LONG).show()
                    dialog.dismissDialog()
                }
            })
            .showDialog()

Summary of stepping on the pit

1. Dialog size failure problem

When LayoutInflate is used, the inflate setting dialog size is invalid.

2. Setting of rounded corners

The choice of shape and cardview
When using shape, the rounded corners become invalid when the background of the dialog changes. You can consider using cardview as the layout. If the style of the dialog hardly needs to be changed, shape can be used.

3、NoClassDefFoundError

When you encounter your java project in this article, you may not introduce the kotlin environment
reference article

end

aar download

Guess you like

Origin blog.csdn.net/qq_38350635/article/details/100052362