android封装框架入门之从自定义对话框开始callback帮你忙

android封装框架入门之从封装确定、取消对话框开始

尊重原创,转载请注明出处:原文查看惊喜更多 http://blog.csdn.net/qq137722697

最近,封装了一个轻量级的网络异步网络请求框架MHttpUtils(传送门),由于非常喜欢RxJava和Retrofit等的链式编程风格,于是自己捣鼓着按这种风格来封装,期间的一些封装思路抽取出来以备记录查阅。

为什么要封装

封装在减少重复代码的同时还能提高开发效率,这便是java中的提高代码重用性的思想,好的封装还能提高app的性能和效率。

封装应有哪些特点

1、易用性

封装的框架应该要容易使用,减少代码量,降低入门的门槛,提供相应的用户操作反馈回调,使用者只用关心经常变动的地方。

2、实用性

封装的框架应该要具有很好的实用性,否则封装就没有了意义

3、尽量保证单例

保持单例主要是为了减少内存资源的占用率,提高app的效率。(这里说的尽量,因为有些东西使用单例模式反而会有诸多限制)

开始封装确定、取消对话框

下面通过封装一个确定、取消对话框的简单例子来看看一种封装的思路。

以前你可能会在每个需要使用对话框的地方写上下面的代码:

        AlertDialog.Builder builder = new AlertDialog.Builder(context);      
        builder.setTitle(title);       
        builder.setMessage(message);      
        builder.setIcon(iconResId);      
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //取消的逻辑处理
            }
        });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //确定的逻辑处理
            }
        });
        builder.create().show();

看着不多,如果是同一个类有多处调用的话还可以提为全局变量,但是如果有很多activity都要调用的话就觉得好没意义,必须抽取出来呀。

首先来看如何保证单例(必须单例模式啊):

//确定、取消对话框
public class MDialog {

    private static MDialog mDialog;

    private MDialog() {
    }

    public static MDialog build() {
        if (mDialog == null) {
            mDialog = new MDialog();
        }
        return mDialog;
    }
}

再来考虑一下哪些是用户经常变动的属性,写了那么多builder的你一定知道title、message、icon是由用户决定的,其实既然抽取出来了,在哪里显示的话一定要告诉MDialog,所以还要加上一个上下文对象context。

为MDialog加上title、message、icon、context四个属性,如何赋值呢?又如何像rxjava、retrofit等的一条链的就写完整个调用过程呢?

我猜你肯定想到链式编程了,链式编程的核心思想就是方法的返回值为对象自己,这样每调用一个方法返回的还是对象本身,那么有多少这样的方法就能调多少了。

完善一下代码:

//确定、取消对话框
public class MDialog {
    ...//省略了上面的代码
    //设置上下文对象     
    public MDialog with(Context context) {
        this.context = context;
        return this;
    }

    //设置标题
    public MDialog title(String title) {
        this.title = title;
        return this;
    }

   // 设置消息
    public MDialog message(String message) {
        this.message = message;
        return this;
    }

   //设置图标资源id
    public MDialog iconResId(int iconResId) {
        this.iconResId = iconResId;
        return this;
    }
}

重点来了,用户点击确定之后的逻辑处理应该由调用者自行处理,这里就要使用非常有用的回调思想了,提供一个接口,用户实现了这个接口,当用户交互的时候触发某个事件而回调给用户实现的这个接口中。

如何定义回调接口?用户交互的无非就是点击确认、取消两个按钮,所以这样定义:

interface IOnClickCallback {
        void onOk();//点击确定的时候回调
        void onCancel();//点击取消的时候回调
    }

细心的你会发现其实很多时候用户点击取消是不需要做任何事的,如何让onCancel方法可以重写但又不是必须重写呢?对,抽象类就可以做到,所以我们改造一下上面的代码(效果在下面给出):

  interface IOnClickCallback {
        void onOk();//点击确定的时候回调
    }
    //这里加上static是因为这个接口是写在MDialog中的,属于内部类
   public static abstract class OnClickCallback implements IOnClickCallback {
        public void onCancel() {//点击取消的时候回调

        }
    }

最后调用一个show方法即显示对话框:

public void show(final OnClickCallback callback) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        if (!TextUtils.isEmpty(title)) {
            builder.setTitle(title);
        }
        if (!TextUtils.isEmpty(message)) {
            builder.setMessage(message);
        }
        if (iconResId != 0) {
            builder.setIcon(iconResId);
        }
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                callback.onCancel();//点击取消的时候回调
            }
        });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                callback.onOk();//点击确认的时候回调
            }
        });
        builder.create().show();
    }

至此,所有的封装已经完毕,贴一下完整的代码:

import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;

/**
 * 自定义确定取消对话框
 * Created by HDL on 2016/11/22.
 */
//确定、取消对话框
public class MDialog {
    private static MDialog mDialog;
    private String title;//标题
    private String message;//提示内容
    private int iconResId;//图标
    private Context context;//上下文对象


    private MDialog() {
    }


    public static MDialog build() {
        if (mDialog == null) {
            mDialog = new MDialog();
        }
        return mDialog;
    }

    //设置上下文对象
    public MDialog with(Context context) {
        this.context = context;
        return this;
    }

    // 设置标题
    public MDialog title(String title) {
        this.title = title;
        return this;
    }

    //设置消息
    public MDialog message(String message) {
        this.message = message;
        return this;
    }

    //设置图标
    public MDialog iconResId(int iconResId) {
        this.iconResId = iconResId;
        return this;
    }
    //显示对话框
    public void show(final OnClickCallback callback) {
    //这里建议使用V7包中的AlertDialog,导包见头文件
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        if (!TextUtils.isEmpty(title)) {
            builder.setTitle(title);
        }
        if (!TextUtils.isEmpty(message)) {
            builder.setMessage(message);
        }
        if (iconResId != 0) {
            builder.setIcon(iconResId);
        }
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                callback.onCancel();
            }
        });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                callback.onOk();
            }
        });
        builder.create().show();
    }

    interface IOnClickCallback {
        void onOk();//点击确定的时候回调
    }

    public static abstract class OnClickCallback implements IOnClickCallback {
        public void onCancel() {//点击取消的时候回调

        }
    }
}

使用

下面来看看怎么使用(是不是没有重写):

大多数情况下是这样使用的:
1、设置标题、内容、处理确定逻辑

 MDialog.build()
                .with(this)
                .title("警告")
                .message("您确定要删除吗?")
                .show(new MDialog.OnClickCallback() {
                    @Override
                    public void onOk() {
                        ToastUtils.showMsg(MDialogDemoActivity.this, "点击确定了");
                    }
                });

是不是没有重写onCancel方法?因为很多时候是不需要处理的,如果需要,重写一下就可以了

这里写图片描述

2、全部调用

          MDialog.build()
                .with(this)
                .title("警告")
                .message("您确定要删除吗?")
                .iconResId(R.mipmap.warning)
                .show(new MDialog.OnClickCallback() {
                    @Override
                    public void onOk() {
                        ToastUtils.showMsg(MDialogDemoActivity.this, "点击确定了");
                    }

                    @Override
                    public void onCancel() {
                        ToastUtils.showMsg(MDialogDemoActivity.this, "点击取消了");
                    }
                });

这里写图片描述

3、只设置内容
注意:当不设置title的时候,设置了icon,icon也是不显示出来的

         MDialog.build()
                .with(this)
                .message("您确定要删除吗?")
                .show(new MDialog.OnClickCallback() {
                    @Override
                    public void onOk() {
                        ToastUtils.showMsg(MDialogDemoActivity.this, "点击确定了");
                    }
                });

这里写图片描述

验证单例

要验证其实很简单,只需将show方法的返回值类型从void改为对象本身即MDialog,然后在三个Activity中调用MDialog,然后答应一下对象就知道是不是同一个对象了。

下图是单例的验证:

这里写图片描述

是同一个吧,验证搞定。

总结

以上只是我在封装框架过程中使用到的思想,demo也比较简单,有人可能会觉得dialog不会封装这麻烦的,仁者见仁智者见智吧,只是提供一种思路,如果你觉得这篇文章还不错,顶一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值