您的位置:首页 > 移动开发 > Android开发

android中的自定义封装易用的Dialog

2017-06-08 18:25 375 查看
[html] view
plain copy

print?

<resources>

<!-- Base application theme. -->

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

<!-- Customize your theme here. -->

<item name="colorPrimary">@color/colorPrimary</item>

<item name="colorPrimaryDark">@color/colorPrimaryDark</item>

<item name="colorAccent">@color/colorAccent</item>

</style>

<style name="text_18_ffffff">

<item name="android:textSize">18.0dip</item>

<item name="android:textColor">#ffffffff</item>

</style>

<style name="text_16_666666">

<item name="android:textSize">16.0dip</item>

<item name="android:textColor">#ff666666</item>

</style>

<style name="sdw_white">

<item name="android:shadowColor">#7fffffff</item>

<item name="android:shadowDx">0.0</item>

<item name="android:shadowDy">0.65</item>

<item name="android:shadowRadius">1.0</item>

</style>

<style name="sdw_79351b">

<item name="android:shadowColor">#ff79351b</item>

<item name="android:shadowDx">0.0</item>

<item name="android:shadowDy">1.0</item>

<item name="android:shadowRadius">1.0</item>

</style>

<style name="text_15_ffffff_sdw" parent="@style/sdw_79351b">

<item name="android:textSize">15.0dip</item>

<item name="android:textColor">#ffffffff</item>

</style>

<style name="text_15_666666_sdw" parent="@style/sdw_white">

<item name="android:textSize">15.0dip</item>

<item name="android:textColor">#ff666666</item>

</style>

<style name="Dialog" parent="android:style/Theme.Dialog">

<item name="android:background">#00000000</item>

<item name="android:windowBackground">@android:color/transparent</item>

<item name="android:windowNoTitle">true</item>

<item name="android:windowIsFloating">true</item>

</style>

<style name="weekName">

<item name="android:layout_width">0.0dip</item>

<item name="android:layout_height">wrap_content</item>

<item name="android:layout_gravity">center</item>

<item name="android:layout_weight">1.0</item>

<item name="android:gravity">center</item>

<item name="android:textColor">#ffffffff</item>

<item name="android:textSize">14sp</item>

</style>

<style name="main_bar_text_style">

<item name="android:textColor">#ffffffff</item>

<item name="android:textStyle">bold</item>

<item name="android:textSize">18sp</item>

</style>

</resources>

再来四个drawable资源文件,两个是确定和取消按钮的样式,其他的两个用于弹出框整体浮层的背景和对话框整体的一个样式

[html] view
plain copy

print?

<?xml version="1.0" encoding="utf-8"?>

<selector

xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true"

android:drawable="@drawable/btn_ok_pressed" />

<item android:drawable="@drawable/btn_ok_normal" />

</selector>

[html] view
plain copy

print?

<?xml version="1.0" encoding="utf-8"?>

<selector

xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/btn_cancel_pressed" />

<item android:state_enabled="true" android:drawable="@drawable/btn_cancel_normal" />

</selector>

[html] view
plain copy

print?

<?xml version="1.0" encoding="utf-8"?>

<layer-list

xmlns:android="http://schemas.android.com/apk/res/android">

<item>

<shape android:shape="rectangle">

<gradient android:startColor="#ffe7e7e7" android:endColor="#ffe7e7e7" android:angle="0.0" />

<corners android:topLeftRadius="0.0dip" android:topRightRadius="0.0dip" android:bottomLeftRadius="5.0px" android:bottomRightRadius="5.0px" />

</shape>

</item>

</layer-list>

[html] view
plain copy

print?

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="rectangle" >

<solid android:color="#56abe4" />

<stroke

android:width="0.5dp"

android:color="#56abe4" />

<corners android:radius="15dp" />

</shape>

布局文件:

[html] view
plain copy

print?

<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:clickable="true"

android:orientation="vertical"

android:padding="20.0dip" >

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:background="@drawable/bg_bombbox"

android:orientation="vertical" >

<TextView

android:id="@+id/title"

style="@style/text_18_ffffff"

android:layout_width="fill_parent"

android:layout_height="40.0dip"

android:gravity="center"

android:text="@string/title_alert"

android:visibility="visible" />

<LinearLayout

android:id="@+id/content"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center" >

<TextView

android:id="@+id/message"

style="@style/text_16_666666"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="left|center"

android:lineSpacingMultiplier="1.5"

android:minHeight="120.0dip"

android:paddingBottom="15.0dip"

android:paddingLeft="20.0dip"

android:paddingRight="20.0dip"

android:paddingTop="15.0dip" />

</LinearLayout>

<View

android:layout_width="fill_parent"

android:layout_height="1.0px"

android:background="#ffd0d0d0" />

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="60.0dip"

android:layout_gravity="bottom"

android:background="@drawable/dialog_bottom_bg"

android:gravity="center"

android:orientation="horizontal" >

<Button

android:id="@+id/positiveButton"

style="@style/text_15_ffffff_sdw"

android:layout_width="114.0dip"

android:layout_height="40.0dip"

android:background="@drawable/btn_ok_selector"

android:gravity="center"

android:text="@string/ok" />

<Button

android:id="@+id/negativeButton"

style="@style/text_15_666666_sdw"

android:layout_width="114.0dip"

android:layout_height="40.0dip"

android:layout_marginLeft="20.0dip"

android:background="@drawable/btn_cancel_selector"

android:gravity="center"

android:text="@string/cancel" />

</LinearLayout>

</LinearLayout>

</FrameLayout>



当然你可以去自定义你的对话框的样式和布局,可以根据个人喜好来定,但是这不是今天的重点.

CustomDialog自定义View类:

[java] view
plain copy

print?

package com.mikyou.myguardian.myview;

import android.app.Dialog;

import android.content.Context;

import android.content.DialogInterface;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup.LayoutParams;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.TextView;

public class CustomDialog extends Dialog {

public CustomDialog(Context context) {

super(context);

}

public CustomDialog(Context context, int theme) {

super(context, theme);

}

public static class Builder {

private Context context;

private String title;

private String message;

private String positiveButtonText;

private String negativeButtonText;

private View contentView;

private OnClickListener positiveButtonClickListener;

private OnClickListener negativeButtonClickListener;

public Builder(Context context) {

this.context = context;

}

public Builder setMessage(String message) {

this.message = message;

return this;

}

/**

* Set the Dialog message from resource

*

* @param title

* @return

*/

public Builder setMessage(int message) {

this.message = (String) context.getText(message);

return this;

}

/**

* Set the Dialog title from resource

*

* @param title

* @return

*/

public Builder setTitle(int title) {

this.title = (String) context.getText(title);

return this;

}

/**

* Set the Dialog title from String

*

* @param title

* @return

*/

public Builder setTitle(String title) {

this.title = title;

return this;

}

public Builder setContentView(View v) {

this.contentView = v;

return this;

}

/**

* Set the positive button resource and it's listener

*

* @param positiveButtonText

* @return

*/

public Builder setPositiveButton(int positiveButtonText,

OnClickListener listener) {

this.positiveButtonText = (String) context

.getText(positiveButtonText);

this.positiveButtonClickListener = listener;

return this;

}

public Builder setPositiveButton(String positiveButtonText,

OnClickListener listener) {

this.positiveButtonText = positiveButtonText;

this.positiveButtonClickListener = listener;

return this;

}

public Builder setNegativeButton(int negativeButtonText,

OnClickListener listener) {

this.negativeButtonText = (String) context

.getText(negativeButtonText);

this.negativeButtonClickListener = listener;

return this;

}

public Builder setNegativeButton(String negativeButtonText,

OnClickListener listener) {

this.negativeButtonText = negativeButtonText;

this.negativeButtonClickListener = listener;

return this;

}

public CustomDialog create() {

LayoutInflater inflater = (LayoutInflater) context

.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

// instantiate the dialog with the custom Theme

final CustomDialog dialog = new CustomDialog(context, R.style.Dialog);

View layout = inflater.inflate(R.layout.dialog_normal_layout, null);

dialog.addContentView(layout, new LayoutParams(

LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

// set the dialog title

((TextView) layout.findViewById(R.id.title)).setText(title);

// set the confirm button

if (positiveButtonText != null) {

((Button) layout.findViewById(R.id.positiveButton))

.setText(positiveButtonText);

if (positiveButtonClickListener != null) {

((Button) layout.findViewById(R.id.positiveButton))

.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

positiveButtonClickListener.onClick(dialog,

DialogInterface.BUTTON_POSITIVE);

}

});

}

} else {

// if no confirm button just set the visibility to GONE

layout.findViewById(R.id.positiveButton).setVisibility(

View.GONE);

}

// set the cancel button

if (negativeButtonText != null) {

((Button) layout.findViewById(R.id.negativeButton))

.setText(negativeButtonText);

if (negativeButtonClickListener != null) {

((Button) layout.findViewById(R.id.negativeButton))

.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

negativeButtonClickListener.onClick(dialog,

DialogInterface.BUTTON_NEGATIVE);

}

});

}

} else {

// if no confirm button just set the visibility to GONE

layout.findViewById(R.id.negativeButton).setVisibility(

View.GONE);

}

// set the content message

if (message != null) {

((TextView) layout.findViewById(R.id.message)).setText(message);

} else if (contentView != null) {

// if no message set

// add the contentView to the dialog body

((LinearLayout) layout.findViewById(R.id.content))

.removeAllViews();

((LinearLayout) layout.findViewById(R.id.content)).addView(

contentView, new LayoutParams(

LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT));

}

dialog.setContentView(layout);

return dialog;

}

}

}

到这里一个自定义View大体工作就完成了,可以测试了,然后通过测试编码过程然后一步一步优化即可.

测试Activity的布局只有三个Button,用于点击后弹出三个不一样的对话框,所以布局很简单就贴了,那么我们还是来一起看下MainActivity

这种使用一般普通的方法.

[java] view
plain copy

print?

package com.mikyou.dialogdemo;

import android.content.DialogInterface;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Toast;

import com.mikyou.dialogdemo.myview.CustomDialog;

public class MainActivity extends AppCompatActivity {

public void dialog1(View view){//弹出第一个对话框

CustomDialog.Builder dialog=new CustomDialog.Builder(this);

dialog.setTitle("测试一")

.setMessage("普通文本提示信息对话框")

.setPositiveButton("确定", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

}

}).setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).create().show();

}

public void dialog2(View view){//弹出第二个对话框

CustomDialog.Builder dialog=new CustomDialog.Builder(this);

dialog.setTitle("测试二")

.setMessage("密码错误")

.setPositiveButton("重新输入", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "重新输入", Toast.LENGTH_SHORT).show();

}

}).setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).create().show();

}

public void dialog3(View view){//弹出第三个对话框

View customView =View.inflate(this,R.layout.input_text_dialog,null);

CustomDialog.Builder dialog=new CustomDialog.Builder(this);

dialog.setTitle("测试三带有自定义View的布局")

.setContentView(customView)//设置自定义customView

.setPositiveButton("确定", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

}

}).setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

dialogInterface.dismiss();

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).create().show();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {

}

}

运行结果:







注意:我们可以很清楚从测试的activity中可以发现,这三个方法中的代码几乎是一样的,只是设置内容和布局不一样,写了这么多代码实际上更多是的毫无技术含量,有的人说不碍事粘贴复制呗,粘贴复制这种最傻的方式我们就不说了.所以我们能不能想想将他们共同的部分抽取出来,把不一样或者会变化的内容作为参数传进去.

封装的思路:

看到这个第一时间就是写一个类利用设计模式中的组合模式的思想,在我们的自定义的类中保存CustomDialog引用,然后就去操作这个类.

然后仔细想下需要注意几点:

第一点,我们可以看到确定和取消按钮都有一个点击事件的回调监听器,这个监听器的设计的初衷就是为了让用户点击确定后去实现确定的逻辑代码,点击取消后去实现取消的逻辑代码,所以必须将该接口抛给用户去处理,因为确定和取消后的逻辑并不是我们所能控制的.所以最后就可以得出就是我们必须要去自定义一个事件监听器,让我们自定义这个监听器去绑定和联系确定和取消点击事件,也就是可以理解为把原来在确定和取消点击事件做的业务逻辑委派给我们自己定义事件监听器统一管理和操作.

第二点,就是传数据,具体要传入哪些数据呢?这不是我说了算,也不是你说了算,而是根据里面逻辑具体需要什么,并且传入数据是变化的不是固定的.

所以我们就可以大概罗列一下需要哪些参数:

                 1,首先上下文对象context(因为在初始化CustomDialog.Builder对象需要,以及如果传入一个自定布局加载成一个view对象的时候需要上下文对象)

2,然后就是传入标题(title),内容(message),布局id,这里需要注意一下,就是message和布局id(用于自定义view对话框)是互斥关系

也就是设置了内容再去设置布局id的view后者是无效有冲突.所以,我们也很容易想到一点就是初始化我们的这个封装的对话框应该有两种方式分别是文本类型和自定义view界面类型,实际上也就引出了我们这个自定义的类中应该两个构造器重载,一个用与初始化文本类型,一个是用于自定义view类型,然后还需要传入两个button需要显示文本内容

第三点,就是是否暴露一些数据接口用于方便用户后期的操作,这里有时候不要,看实际情况.仔细想想我们这里需要吗?实际上是需要就是我们在使用自定义view的对象,因为我们有时候需要去操作自定义布局中的一些控件,就比如上面最后例子就是输入密码,可能我们需要获得EditText中的内容,首先需要拿到EditText对象,所以需要传出一个自定义布局的view对象,所以我就提供一个setter和getter方法留给外部用户使用,这里为了后面的使用方便我就把这个view对象使用回调方法将其回调出去.

那么具体来看下代码的实现:

[java] view
plain copy

print?

package com.mikyou.dialogdemo.myview;

import android.content.Context;

import android.content.DialogInterface;

import android.view.View;

import android.widget.Toast;

/**

* @自定义封装的通用对话框:MikyouCommonDialog

*

* Created by mikyou on 16-7-21.

* @param dialogTitle 对话框的标题

* @param dialogMessage 对话框的内容

* @param positiveText 表示是确定意图的按钮上text文本

* @param negativeText 表示是取消意图的按钮上text文本

* @param customeLayoutId 对话框自定义布局的id 若没有自定义布局  默认传入0

* @param context 上下文对象

* @param dialogView 自定义布局的View对象,提供被外界访问的接口get和set方法,并且利用自定义的监听器将view对象回调出去

* @param listener 监听器 用于将确定和取消意图的两个点击事件监听器,合成一个监听器,并传入一个标记变量区别确定和取消意图

*/

public class MikyouCommonDialog {

private Context context;

private int customeLayoutId;

private String dialogTitle;

private String dialogMessage;

private String positiveText;

private String negativeText;

private View dialogView;

private OnDialogListener listener;

//带有自定义view的构造器

public MikyouCommonDialog(Context context, int customeLayoutId, String dialogTitle, String positiveText, String negativeText) {

this.context = context;

this.customeLayoutId = customeLayoutId;

this.dialogTitle = dialogTitle;

this.positiveText = positiveText;

this.negativeText = negativeText;

this.dialogView=View.inflate(context,customeLayoutId,null);

}

//不带自定义view的构造器

public MikyouCommonDialog(Context context, String dialogMessage,String dialogTitle, String positiveText, String negativeText) {

this.context = context;

this.dialogTitle = dialogTitle;

this.dialogMessage = dialogMessage;

this.positiveText = positiveText;

this.negativeText = negativeText;

}

public View getDialogView() {

return dialogView;

}

public void setDialogView(View dialogView) {

this.dialogView = dialogView;

}

public void showDialog(){

CustomDialog.Builder dialog=new CustomDialog.Builder(context);

dialog.setTitle(dialogTitle);//设置标题

//注意:dialogMessage和dialogView是互斥关系也就是dialogMessage存在dialogView就不存在,dialogView不存在dialogMessage就存在

if (dialogMessage!=null){

Toast.makeText(context, "sddsdsds", Toast.LENGTH_SHORT).show();

dialog.setMessage(dialogMessage);//设置对话框内容

}else{

dialog.setContentView(dialogView);//设置对话框的自定义view对象

}

/**

* 尽管有两个点击事件监听器,可以通过我们自定义的监听器设置一个标记变量,从而可以实现将两个点击事件合并成一个

* 监听器OnDialogListener

* */

//确定意图传入positive标记值

dialog.setPositiveButton(positiveText, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int which) {

dialogInterface.dismiss();

if (listener!=null){

listener.dialogListener("positive",dialogView,dialogInterface,which);

}

}

//取消意图传入negative标记值

}).setNegativeButton(negativeText, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int which) {

dialogInterface.dismiss();

if (listener!=null){

listener.dialogListener("negative",dialogView,dialogInterface,which);

}

}

}).create().show();

}

//注册监听器方法

public MikyouCommonDialog setOnDiaLogListener(OnDialogListener listener){

this.listener=listener;

return this;//把当前对象返回,用于链式编程

}

//定义一个监听器接口

public interface OnDialogListener{

//customView 这个参数需要注意就是如果没有自定义view,那么它则为null

public void dialogListener(String btnType, View customView, DialogInterface dialogInterface, int which);

}

}

实现方式:

[java] view
plain copy

print?

private void popInputPwdDialog() {

new MikyouCommonDialog(this,R.layout.input_pwd_dialog,"输入安全密码","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogListener(String btnType, View customView, DialogInterface dialogInterface, int which) {

switch (btnType){

case "positive"://点击确定按钮的操作

EditText eTPwd=(EditText) customView.findViewById(R.id.input_pwd);

checkAndSavePwd("input",eTPwd.getText().toString(),"");

break;

case "negative"://点击取消按钮的操作

break;

}

}

}).showDialog();

}

测试的Activity那么我们一起来对比一下封装后的代码:

[java] view
plain copy

print?

package com.mikyou.dialogdemo;

import android.content.DialogInterface;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Toast;

import com.mikyou.dialogdemo.myview.MikyouCommonDialog;

public class MainActivity extends AppCompatActivity {

public void dialog1(View view){//弹出第一个对话框

new MikyouCommonDialog(this,"普通文本提示信息对话框","测试一","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogListener(String btnType, View customView, DialogInterface dialogInterface, int which) {

switch (btnType){

case "positive":

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

break;

case "negative":

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

break;

}

}

}).showDialog();

}

public void dialog2(View view){//弹出第二个对话框

new MikyouCommonDialog(this,"密码错误","测试二","重新输入","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogListener(String btnType, View customView, DialogInterface dialogInterface, int which) {

switch (btnType){

case "positive":

Toast.makeText(MainActivity.this, "重新输入", Toast.LENGTH_SHORT).show();

break;

case "negative":

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

break;

}

}

}).showDialog();

}

public void dialog3(View view){//弹出第三个对话框

new MikyouCommonDialog(this,R.layout.input_text_dialog,"测试三带有自定义View的布局","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogListener(String btnType, View customView, DialogInterface dialogInterface, int which) {

switch (btnType){

case "positive":

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

break;

case "negative":

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

break;

}

}

}).showDialog();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {

}

}

是不是感觉比开始那种最原始方法要好些,代码逻辑更清晰些.我们现在的这种封装还能进一步优化吗?我们都知道封装思想在于什么,在于用户外部接口调用传入数据不一样进行操作不一样,但是整个封装的框架是一样的.所以仔细观察一下上面的代码,是不是会发现那三个方法中的switch显得很鸡肋,因为在三个方法中还需要去判断是否是确定还是取消类型,并且在封装类里面我们还得把标记的字符串变量通过回调方法回调出来,感觉就有点多此一举了.

优化思想:

就是我们不需要传入标记变量并且不需要在外部调用的时候使用switch来判断,而是采用两个回调方法,一个是确定类型的回调方法,另一个则是取消类型的回调方法.然后分别在不同类型回调方法实现各自的业务逻辑.这种方式实际上最原始那种方式也就是这样处理.

看下优化的代码:

[java] view
plain copy

print?

package com.mikyou.myguardian.myview;

import android.content.Context;

import android.content.DialogInterface;

import android.view.View;

/**

* @自定义封装的通用对话框:MikyouCommonDialog

*

* Created by mikyou on 16-7-21.

* @param dialogTitle 对话框的标题

* @param dialogMessage 对话框的内容

* @param positiveText 表示是确定意图的按钮上text文本

* @param negativeText 表示是取消意图的按钮上text文本

* @param customeLayoutId 对话框自定义布局的id 若没有自定义布局  默认传入0

* @param context 上下文对象

* @param dialogView 自定义布局的View对象,提供被外界访问的接口get和set方法,并且利用自定义的监听器将view对象回调出去

* @param listener 监听器 用于将确定和取消意图的两个点击事件监听器,合成一个监听器,并传入一个标记变量区别确定和取消意图

*/

public class MikyouCommonDialog2 {

private Context context;

private int customeLayoutId;

private String dialogTitle;

private String dialogMessage;

private String positiveText;

private String negativeText;

private View dialogView;

private OnDialogListener listener;

//带有自定义view的构造器

public MikyouCommonDialog2(Context context, int customeLayoutId, String dialogTitle, String positiveText, String negativeText) {

this.context = context;

this.customeLayoutId = customeLayoutId;

this.dialogTitle = dialogTitle;

this.positiveText = positiveText;

this.negativeText = negativeText;

this.dialogView=View.inflate(context,customeLayoutId,null);

}

//不带自定义view的构造器

public MikyouCommonDialog2(Context context, String dialogMessage, String dialogTitle, String positiveText, String negativeText) {

this.context = context;

this.dialogTitle = dialogTitle;

this.dialogMessage = dialogMessage;

this.positiveText = positiveText;

this.negativeText = negativeText;

}

public View getDialogView() {

return dialogView;

}

public void setDialogView(View dialogView) {

this.dialogView = dialogView;

}

public void showDialog(){

CustomDialog.Builder dialog=new CustomDialog.Builder(context);

dialog.setTitle(dialogTitle);//设置标题

//注意:dialogMessage和dialogView是互斥关系也就是dialogMessage存在dialogView就不存在,dialogView不存在dialogMessage就存在

if (dialogMessage!=null){

dialog.setMessage(dialogMessage);//设置对话框内容

}else{

dialog.setContentView(dialogView);//设置对话框的自定义view对象

}

dialog.setPositiveButton(positiveText, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int which) {

dialogInterface.dismiss();

if (listener!=null){

listener.dialogPositiveListener(dialogView,dialogInterface,which);

}

}

}).setNegativeButton(negativeText, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int which) {

dialogInterface.dismiss();

if (listener!=null){

listener.dialogNegativeListener(dialogView,dialogInterface,which);

}

}

}).create().show();

}

//注册监听器方法

public MikyouCommonDialog2 setOnDiaLogListener(OnDialogListener listener){

this.listener=listener;

return this;//把当前对象返回,用于链式编程

}

//定义一个监听器接口

public interface OnDialogListener{

//customView 这个参数需要注意就是如果没有自定义view,那么它则为null

public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which);

public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which);

}

}

测试方式:

[java] view
plain copy

print?

private void popInputPwdDialog() {

new MikyouCommonDialog2(this,R.layout.input_pwd_dialog,"输入安全密码","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog2.OnDialogListener() {

@Override

public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which) {//点击确定按钮的操作

EditText eTPwd=(EditText) customView.findViewById(R.id.input_pwd);

checkAndSavePwd("input",eTPwd.getText().toString(),"");

}

@Override

public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which) {//点击取消按钮的操作

+

}

}).showDialog();

}

测试Activity:

[java] view
plain copy

print?

package com.mikyou.dialogdemo;

import android.content.DialogInterface;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Toast;

import com.mikyou.dialogdemo.myview.MikyouCommonDialog;

public class MainActivity extends AppCompatActivity {

public void dialog1(View view){//弹出第一个对话框

new MikyouCommonDialog(this,"普通文本提示信息对话框","测试一","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

}

@Override

public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).showDialog();

}

public void dialog2(View view){//弹出第二个对话框

new MikyouCommonDialog(this,"密码错误","测试二","重新输入","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "重新输入", Toast.LENGTH_SHORT).show();

}

@Override

public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).showDialog();

}

public void dialog3(View view){//弹出第三个对话框

new MikyouCommonDialog(this,R.layout.input_text_dialog,"测试三带有自定义View的布局","确定","取消")

.setOnDiaLogListener(new MikyouCommonDialog.OnDialogListener() {

@Override

public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();

}

@Override

public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which) {

Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();

}

}).showDialog();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: