博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android——DialogFragment(二)封装创建通用的 CommonDialogFragment
阅读量:2082 次
发布时间:2019-04-29

本文共 8585 字,大约阅读时间需要 28 分钟。

对于DialogFragment不熟的同学请查看

首先看下我们将要实现的效果

1、创建通用的 CommonDialogFragment

这个类是 DialogFragment 的子类,对 DialogFragment 进行封装,依赖外部传入的 AlertDialog 来构建,同时也处理了 DialogFragment 中 AlertDialog 不能设置外部取消的问题。

public class CommonDialogFragment extends DialogFragment {
/** * 监听弹出窗是否被取消 */ private OnDialogCancelListener mCancelListener; /** * 回调获得需要显示的dialog */ private OnCallDialog mOnCallDialog; public interface OnDialogCancelListener {
void onCancel(); } public interface OnCallDialog {
Dialog getDialog(Context context); } public static CommonDialogFragment newInstance(OnCallDialog call, boolean cancelable) { return newInstance(call, cancelable, null); } public static CommonDialogFragment newInstance(OnCallDialog call, boolean cancelable, OnDialogCancelListener cancelListener) { CommonDialogFragment instance = new CommonDialogFragment(); instance.setCancelable(cancelable); instance.mCancelListener = cancelListener; instance.mOnCallDialog = call; return instance; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { if (null == mOnCallDialog) { super.onCreateDialog(savedInstanceState); } return mOnCallDialog.getDialog(getActivity()); } @Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { //在5.0以下的版本会出现白色背景边框,若在5.0以上设置则会造成文字部分的背景也变成透明 if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { //目前只有这两个dialog会出现边框 if(dialog instanceof ProgressDialog || dialog instanceof DatePickerDialog) { getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } } Window window = getDialog().getWindow(); WindowManager.LayoutParams windowParams = window.getAttributes(); windowParams.dimAmount = 0.0f; window.setAttributes(windowParams); } } @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); if (mCancelListener != null) { mCancelListener.onCancel(); } }}

可以看到这个类的代码量也是很少的,先定义了两个接口 OnDialogCancelListener,OnCallDialog,前者用于监听弹出窗是否被取消,后者则可以让我们回调获得想要显示的 Dialog,可以看到在 onCreateDialog() 中我们返回的 是 mOnCallDialog.getDialog(getActivity);,当我们在传入 Dialog 的时候,便会回调到此处,让 onCreateDialog() 返回我们传入的 Dialog。

接着在 onStart() 中进行了一些特殊性的处理,因为在 5.0 以下的版本,ProgressDialog 和 DatePickerDialog 会出现白色的边框,这使得用户体验非常不好,所以我们要在此处进行相应的处理

最后便是封装我们的构造函数

newInstance(OnCallDialog call, boolean cancelable, OnDialogCancelListener cancelListener),当我们要使用这个 CommonDialogFragment 的时候,先 new 一个 OnCallDialog,将我们想要显示的 Dialog 传进去,cancelable,用于设置对话框是否能被取消,可以看到在 onCancel() 有这样一段代码

if(mCancelListener != null){  mCancelListener.onCancel();}

这便是我们在构造函数中传入 OnCancelListener 的原因,当我们想要做一些取消对话框后的处理时,只要在构造函数中传入 OnCancelListener,实现 onCancel() 方法就行了

2、实现各种类型的 DialogFragment

既然前面我们创建了 CommonFragment 作为所有 DialogFragment 的基类,那么接下来我们当然要好好地来实现各种类型的 DialogFragment 了,我的思路是创建一个 DialogFragmentHelper 作为实现提示框的帮助类,帮我们把代码都封装起来,使用的时候只需要关注与 AlertDialog 的交互,Helper 会帮助我们用 DialogFragment 来进行显示,这样既能统一整个应用的 Dialog 风格,又能让我们实现各种各样的对话框变得相当的简单

在实现 DialogFragmentHelper 之前我们有两件事先要做一下

1、在 styles 文件中定义我们定义我们对话框的风格样式

2、写一个接口,用于 DialogFragmentHelper 与逻辑层之间进行数据监听

public interface IDialogResultListener
{ void onDataResult(T result);}

准备工作做完了,就让我们开工撸 DialogFragmentHelper 吧,因为篇幅有限,我只是代表性的选了其中的一些效果来讲,具体的代码,可以参考下

public class DialogFragmentHelper {
private static final String TAG_HEAD = DialogFragmentHelper.class.getSimpleName(); /** * 加载中的弹出窗 */ private static final int PROGRESS_THEME = R.style.Base_AlertDialog; private static final String PROGRESS_TAG = TAG_HEAD + ":progress"; public static CommonDialogFragment showProgress(FragmentManager fragmentManager, String message){ return showProgress(fragmentManager, message, true, null); } public static CommonDialogFragment showProgress(FragmentManager fragmentManager, String message, boolean cancelable){ return showProgress(fragmentManager, message, cancelable, null); } public static CommonDialogFragment showProgress(FragmentManager fragmentManager, final String message, boolean cancelable , CommonDialogFragment.OnDialogCancelListener cancelListener){ CommonDialogFragment dialogFragment = CommonDialogFragment.newInstance(new CommonDialogFragment.OnCallDialog() { @Override public Dialog getDialog(Context context) { ProgressDialog progressDialog = new ProgressDialog(context, PROGRESS_THEME); progressDialog.setMessage(message); return progressDialog; } }, cancelable, cancelListener); dialogFragment.show(fragmentManager, PROGRESS_TAG); return dialogFragment; } /** * 带输入框的弹出窗 */ private static final int INSERT_THEME = R.style.Base_AlertDialog; private static final String INSERT_TAG = TAG_HEAD + ":insert"; public static void showInsertDialog(FragmentManager manager, final String title, final IDialogResultListener
resultListener, final boolean cancelable){ CommonDialogFragment dialogFragment = CommonDialogFragment.newInstance(new CommonDialogFragment.OnCallDialog() { @Override public Dialog getDialog(Context context) { // ... AlertDialog.Builder builder = new AlertDialog.Builder(context, INSERT_THEME); builder.setPositiveButton(DIALOG_POSITIVE, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if(resultListener != null){ resultListener.onDataResult(editText.getText().toString()); } } }); builder.setNegativeButton(DIALOG_NEGATIVE, null); return builder.create(); } }, cancelable, null); dialogFragment.show(manager, INSERT_TAG); }}

可以看到因为我们实现封装了 CommonFragment,所有这些效果的实现都变得相当的简单吗,这便是封装给我们带来的便利和好处。

就以 加载中的弹出窗 为例,来看看我们是怎么实现的

public static CommonDialogFragment showProgress(FragmentManager fragmentManager, final String message, boolean cancelable            , CommonDialogFragment.OnDialogCancelListener cancelListener){        CommonDialogFragment dialogFragment = CommonDialogFragment.newInstance(new CommonDialogFragment.OnCallDialog() {            @Override            public Dialog getDialog(Context context) {                ProgressDialog progressDialog = new ProgressDialog(context, PROGRESS_THEME);                progressDialog.setMessage(message);                return progressDialog;            }        }, cancelable, cancelListener);        dialogFragment.show(fragmentManager, PROGRESS_TAG);        return dialogFragment;    }

我们先调用了 CommonDialogFragment 的构造函数,将一个 ProgressDialog 传进去,然后依次传入 cancelable 和 cancelListener,最后调用 show() 函数,将DialogFragment 显示出来,因为我们使用了构造函数的重载,可以看到最简单的构造函数只需要传入两个参数就行了,是不是相当的简洁啊。

应该还没忘了我们上面创建了一个 IDialogResultListener<T> 用于 DialogFragment 与逻辑层之间进行数据监听吧,为了能传入各种各样类型的数据,这里我使用了 泛型 来进行处理,就以 带输入框的弹出窗 为例来看看究竟要怎么使用吧

public static void showInsertDialog(FragmentManager manager, final String title, final IDialogResultListener
resultListener, final boolean cancelable){ CommonDialogFragment dialogFragment = CommonDialogFragment.newInstance(new CommonDialogFragment.OnCallDialog() { @Override public Dialog getDialog(Context context) { // ... 这里省略一部分代码 AlertDialog.Builder builder = new AlertDialog.Builder(context, INSERT_THEME); builder.setPositiveButton(DIALOG_POSITIVE, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if(resultListener != null){ resultListener.onDataResult(editText.getText().toString()); } } }); builder.setNegativeButton(DIALOG_NEGATIVE, null); return builder.create(); } }, cancelable, null); dialogFragment.show(manager, INSERT_TAG); }

可以看到我们在showInsertDialog()方法中传入了IDialogResultListener<String> resultListener,当我们想要处理输入的内容的时候,只要在外部调用的时候,new 一个IDialogResultListener 传进去,然后实现onDataResult() 方法就行了

以上便是全文的内容,具体的代码以及示例我都放上 Github 了,有需要的朋友可以去看一下 。

原文链接:

你可能感兴趣的文章
【Linux】vim的简单配置
查看>>
笔记本怎么设置WIfi热点
查看>>
如何实现字符串的反转及替换?
查看>>
Java面试题全集(上)
查看>>
Java面试题全集(中)
查看>>
值传递和引用传递
查看>>
什么情况下用+运算符进行字符串连接比调用StringBuilder对象的append方法连接字符串性能更好?
查看>>
怎么根据Comparable方法中的compareTo方法的返回值的正负 判断升序 还是 降序?
查看>>
理解事务的4种隔离级别
查看>>
常用正则匹配符号
查看>>
建议42: 让工具类不可实例化
查看>>
Java 异步机制与同步机制的区别
查看>>
hibernate的对象三种状态说明
查看>>
什么是N+1查询?
查看>>
直插,快排,堆排,归并排序的分析
查看>>
二叉树的各种操作(面试必备)
查看>>
oracle
查看>>
Struts2中的session、request、respsonse获取方法
查看>>
如何理解MVC模型
查看>>
SpringMVC中乱码解决方案
查看>>