看了很多视频,也在网上找了一些浏览量最多的文章,发现都太难懂或者太复杂,夹杂了很多其他功能,自定义度太高,很繁琐。所以我想写一个基础的自定义Dialog,只涉及基础的自定义,其他复杂的自定义可以在这个的基础上自己添加shape或Backgroud定义颜色和形状。
先看一下效果图
Android 自定义Dialog
下面开始讲解自定义Dialog的步骤
一、第一步,先创建一个dialog的布局layout_custom_dialog,这就是我们弹出的对话框样式(简单)
代码段
代码中父布局中的backgroud设置了布局的圆角,这个比较简单,不会的可以看一下我写的另外一篇文章。
<?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:background="@drawable/bg_custom_dialog"android:gravity="center_horizontal"android:orientation="vertical"><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="提 示"android:textColor="@color/black"android:textSize="20sp"android:textStyle="bold" /><TextViewandroid:id="@+id/message"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="是否确定执行此操作?"android:textColor="@color/black"android:textSize="20sp" /><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_marginTop="20dp"android:background="#888888" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:orientation="horizontal"><TextViewandroid:id="@+id/cancel"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="取消"android:textColor="@color/black"android:textSize="20sp" /><Viewandroid:layout_width="0.5dp"android:layout_height="match_parent"android:background="#888888" /><TextViewandroid:id="@+id/confirm"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="确定"android:textColor="#0582FF"android:textSize="20sp" /></LinearLayout></LinearLayout>
效果图

二、第二步, 我们新建一个java文件,名称为CustomDialog。(重难点)
代码段
一、创建一个classCustomDialog继承Dialog并且实现View.OnClickListener接口。
二、重写CustomDialog和onCreate方法,这样,一个自定义Dialog框架就写好了,接下来需要实现他的功能。
(!!!)我们可以看到第一步写的布局中有很多TextView文本,那么在一个高度自定义的Dialog中是需要能够重新编写这些文字的,所以,我们需要能够设置这些文本的set方法,下面我们来实现set方法。
1、声明控件mTitle, mMessage, mConfirm, mCancel。声明字符串sTitle,sMessage, sConfirm, sCancel。
2、在onCreate方法中找到四个控件。
3、右键点击声明的字符串,generate->setter,按住ctrl键点击sTitle,sMessage, sConfirm, sCancel,创建这四个字符串的set方法,这样就得到了四个set方法,如果调用的时候想要使用链式调用,可以象我这样把四个方法的void改成CustomDialog并且返回this。
4、set方法虽然设置了我们想要的字符串,但是还没有将这些字符串传给我们的布局中,所以我们需要在onCreate方法里设置一下(见代码),如果我们设置的字符串不是空的话,就将其赋值给布局中的text。

三、重头戏来了 !我们在自定义Dialog时设置了两个实现按键功能的cancel和confirm,所以还需要设置监听事件,所以我们还需要在setsConfirm和setsCancel的同时设置监听事件。
1、首先声明两个监听器cancelListener, confirmListener
2、在setsConfirm和setsCancel方法中写两个监听器并且将这两个监听器分别传给上面声明的两个监听器。
3、重写onClick方法,并且在onCreat方法中设置监听器。
四、由于新版本原因以及自定义Dialog时会自动将宽度设置为wrap,所以我们需要自己设置Dialog的宽度,代码如下。另外由于不明确的原因,无法在调用Dialog时设置点击空白处不消失,所以只能在Dialog中设置setCancelable(false);另外,如果调用时发现圆角无法生效,在代码中设置getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))即可。
package com.example.test2.widget;import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;import androidx.annotation.NonNull;import com.example.test2.R;public class CustomDialog extends Dialog implements View.OnClickListener {private TextView mTitle, mMessage, mConfirm, mCancel;private String sTitle, sMessage, sConfirm, sCancel;private View.OnClickListener cancelListener, confirmListener;public CustomDialog setsTitle(String sTitle) {this.sTitle = sTitle;return this;}public CustomDialog setsMessage(String sMessage) {this.sMessage = sMessage;return this;}public CustomDialog setsConfirm(String sConfirm, View.OnClickListener listener) {this.sConfirm = sConfirm;this.confirmListener = listener;return this;}public CustomDialog setsCancel(String sCancel, View.OnClickListener listener) {this.sCancel = sCancel;this.cancelListener = listener;return this;}public CustomDialog(@NonNull Context context) {super(context);}public CustomDialog(@NonNull Context context, int themeResId) {super(context, themeResId);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_custom_dialog);getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));setCancelable(false);//自定义Dialog宽度WindowManager m = getWindow().getWindowManager();Display d = m.getDefaultDisplay();WindowManager.LayoutParams p = getWindow().getAttributes();Point size = new Point();d.getSize(size);p.width = (int) ((size.x)*0.7); //设置为屏幕的0.7倍宽度getWindow().setAttributes(p);mTitle = findViewById(R.id.title);mMessage = findViewById(R.id.message);mCancel = findViewById(R.id.cancel);mConfirm = findViewById(R.id.confirm);if (!TextUtils.isEmpty(sTitle)) {mTitle.setText(sTitle);}if (!TextUtils.isEmpty(sMessage)) {mMessage.setText(sMessage);}if (!TextUtils.isEmpty(sCancel)) {mCancel.setText(sCancel);}if (!TextUtils.isEmpty(sConfirm)) {mConfirm.setText(sConfirm);}mConfirm.setOnClickListener(this);mCancel.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.confirm:if(confirmListener != null){confirmListener.onClick(view);}break;case R.id.cancel:if(cancelListener != null){cancelListener.onClick(view);}break;}}}
三、第三步,新建一个Activity
在布局中写一个按钮,在activity中声明并设置监听,然后就可以直接使用自定义Dialog啦
package com.example.test2;import android.os.Bundle;
import android.view.View;
import android.widget.Button;import androidx.appcompat.app.AppCompatActivity;import com.example.test2.widget.CustomDialog;public class CustomDialogActivity extends AppCompatActivity {private Button mBt;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_custom_dialog);mBt = findViewById(R.id.bt_dialog);mBt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {CustomDialog customDialog = new CustomDialog(CustomDialogActivity.this);customDialog.setsTitle("warning").setsMessage("are you sure?").setsCancel("cancel", new View.OnClickListener() {@Overridepublic void onClick(View view) {customDialog.dismiss();}}).setsConfirm("sure", new View.OnClickListener() {@Overridepublic void onClick(View view) {}}).show();}});}
}















