Android开发之Buidler模式初探结合AlertDialog.Builder解说
那么要为何使用Buidler呢?
是为了将构建复杂对象的过程和它的部件分开由于一个复杂的对象,不但有非常多大量组成部分,如AlertDialog对话框,有非常多组成部件,比方Tittle,Message,icon,PositiveButton等等,但远不止这些,怎样将这些部件装配成一个AlertDialog对话框呢,这个装配程可能也是一个非常复杂的步骤,Builder模式就是为了将部件和组装过程分开。通俗点说,就是我先分开生产好各个组件,然后交由还有一个类去组装这些组件。
怎样使用?
我们来看一下Android内部关于AlertDialog.Builder的源代码便能够知晓。
public class AlertDialog extends Dialog implements DialogInterface {
// Controller, 接受Builder成员变量P中的各个參数
private AlertController mAlert;
// 构造函数
protected AlertDialog(Context context, int theme) {
this(context, theme, true);
}
// 4 : 构造AlertDialog
AlertDialog(Context context, int theme, boolean createContextWrapper) {
super(context, resolveDialogTheme(context, theme), createContextWrapper);
mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(getContext(), this, getWindow());
}
// 实际上调用的是mAlert的setTitle方法
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
}
// 实际上调用的是mAlert的setCustomTitle方法
public void setCustomTitle(View customTitleView) {
mAlert.setCustomTitle(customTitleView);
}
public void setMessage(CharSequence message) {
mAlert.setMessage(message);
}
// AlertDialog其它的代码省略
// ************ Builder为AlertDialog的内部类 *******************
public static class Builder {
// 1 :该类用来存储AlertDialog的各个參数, 比如title, message, icon等.
private final AlertController.AlertParams P;
/**
* Constructor using a context for this builder and the {@link AlertDialog} it creates.
*/
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
}
public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
}
// 2:设置各种參数到P
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
}
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
}
public Builder setIcon(int iconId) {
P.mIconId = iconId;
return this;
}
public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
P.mPositiveButtonText = text;
P.mPositiveButtonListener = listener;
return this;
}
public Builder setView(View view) {
P.mView = view;
P.mViewSpacingSpecified = false;
return this;
}
// 3 : 构建AlertDialog, 传递參数
public AlertDialog create() {
// 调用new AlertDialog构造对象, 而且将參数传递个体AlertDialog
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
// 5 : 将P中的參数应用的dialog中的mAlert对象中
//这一步是核心方法我们等下看源代码继续讲
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
}
public AlertDialog show() {
//6:显示dialog
AlertDialog dialog = create();
dialog.show();
return dialog;
}
}
}
从上面的源代码中我们能够看到,对话框的构建是通过Builder来设置AlertDialog中的title, message, button等參数, 这些參数都存储在类型为AlertController.AlertParams的成员变量P中,AlertController.AlertParams中包括了与之相应的成员变量。在调用Builder类的create函数时才创建AlertDialog, 而且将Builder成员变量P中保存的參数应用到AlertDialog的mAlert对象中,最后调用dialog.show方法显示对话框。
如今我们再来看看即P.apply(dialog.mAlert)代码段。我们看看apply函数的实现 。
public void apply(AlertController dialog) {
if (mCustomTitleView != null) {
dialog.setCustomTitle(mCustomTitleView);
} else {
if (mTitle != null) {
dialog.setTitle(mTitle);
}
if (mIcon != null) {
dialog.setIcon(mIcon);
}
if (mIconId >= 0) {
dialog.setIcon(mIconId);
}
if (mIconAttrId > 0) {
dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
}
}
if (mMessage != null) {
dialog.setMessage(mMessage);
}
if (mPositiveButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
mPositiveButtonListener, null);
}
if (mNegativeButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,
mNegativeButtonListener, null);
}
if (mNeutralButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,
mNeutralButtonListener, null);
}
if (mForceInverseBackground) {
dialog.setInverseBackgroundForced(true);
}
// For a list, the client can either supply an array of items or an
// adapter or a cursor
if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
createListView(dialog);
}
if (mView != null) {
if (mViewSpacingSpecified) {
dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
mViewSpacingBottom);
} else {
dialog.setView(mView);
}
}
}
实际上就是把P中的參数挨个的设置到AlertController中, 也就是AlertDialog中的mAlert对象。从AlertDialog的各个setter方法中我们也能够看到,实际上也都是调用了mAlert相应的setter方法。
综上看完上面源代码之后我们就能够发现,怪不得我们平时调用对话框的时候能够直接使用,AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);不用Alert.Builder方法创建也能够,由于其本质是一样的,Builder仅仅是把组件的生产过程化成一步步实行而已。
这样做有什么实际作用呢?
在Java实际使用中,我们经经常使用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,而且这些资源须要被非常多用户重复共享时,就须要使用池。"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比方数据库的连接池,或许有时一个连接会中断),假设循环再利用这些"断肢",将提高内存使用效率,提高池的性能,而在这里AlertDialog.builder就是这个池,改动Builder模式中p.apply(组装)类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
Android开发之Buidler模式初探结合AlertDialog.Builder解说的更多相关文章
- Android开发之MVP模式的使用
前几天发现,在Android项目代码里有一个Activity类行数居然有1000多行,而600行左右都是逻辑控制,真正和页面控件处理相关的代码不多,虽然可以用#region <>...#e ...
- Android开发之Java集合类性能分析
对于Android开发者来说深入了解Java的集合类很有必要主要是从Collection和Map接口衍生出来的,目前主要提供了List.Set和 Map这三大类的集合,今天Android吧(ard8. ...
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...
- Android开发之Java必备基础
Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...
- Android开发之PopupWindow
/* * Android开发之PopupWindow * * Created on: 2011-8-8 * Author: blueeagle * Email: liujiaxiang@g ...
- Android 开发之旅:深入分析布局文件&又是“Hello World!”
http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...
- android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序
android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序 在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity ...
- Android开发之旅2:HelloWorld项目的目录结构
引言 前面Android开发之旅:环境搭建及HelloWorld,我们介绍了如何搭建Android开发环境及简单地建立一个HelloWorld项目,本篇将通过HelloWorld项目来介绍Androi ...
- Android开发之MdiaPlayer详解
Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...
随机推荐
- Linux经常使用命令(十一) - more
more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最主要的指令就是按空白键(space)就往下一页显示,按 b 键就会 ...
- PreferenceActivity使用示例
MainActivity如下: package cn.testpreferenceactivity; import android.content.SharedPreferences; import ...
- HDU 1007 近期点对
分治法求近期点对 递归将点不断分成小组.计算最短距离.此时的最短距离不过两点都属两块的某一块(这里的切割点是mid点). 还须要考虑两点分属两块的情况. 这时对于选点则把范围缩小到了以mid为中心. ...
- Static关键字的作用及使用
1.使用static声明属性 如果希望一个属性被所有对象共同拥有,可以将其声明为static类型. 声明为static类型的属性或方法,此属性或方法也被称为类方法,可以由类名直接调用. class P ...
- Mac OS提示# 14:自己定义文件图标
本教程的其余部分再一次错过了方法,和一些使用提示,做一些额外的,我们希望对大家有帮助. 自己定义图标 对于Mac OSX用户来说,Dashboard,Dock栏,壁纸以及各种键盘触摸板的快 ...
- hdu 3488 Tour
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3488 题意:给你一个N个顶点M条边的带权有向图,要你把该图分成1个或多个不相交的有向环.且所有定点都只 ...
- IE6,IE7,IE8下报JS错误:expected identifier, string or number的原因及解决的方法
今天在调试一个页面的时候遇到一个问题,在IE9下执行得非常好的脚本,在IE8里打开的时候弹出错误:expected identifier, string or number,依照经验,应该是定义对象的 ...
- 关于hibernate中多对多关系
关于多对多关系 数据库:在使用多对多的关系时,我们能够使用复合主键.也能够不使用,直接引入外键相同能够实现. 在数据库中使用多对多关系时,须要一个中间表. 多对多关系中的数据库结构例如以下: 表:Or ...
- Android周报
Android周报 原文 http://www.race604.com/android-weekly-25/ 文章/教程 使用 Kotlin 开发 Android 应用系列 看起来用 Kotli ...
- Linux共享wifi给Android手机
亲測可行,測试系统:Deepin2014,Ubuntu也一样.步骤很easy. 1.卸载hostapd,sudo apt-get remove hostapd(假设原来装过的话卸载,由于某些版本号不支 ...