-
什么是Buidler模式呢?就是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.
那么要为何使用Buidler呢?
是为了将构建复杂对象的过程和它的部件分开因为一个复杂的对象,不但有很多大量组成部分,如AlertDialog对话框,有很多组成部件,比如Tittle,Message,icon,PositiveButton等等,但远不止这些,如何将这些部件装配成一个AlertDialog对话框呢,这个装配程可能也是一个很复杂的步骤,Builder模式就是为了将部件和组装过程分开。通俗点说,就是我先分开生产好各个组件,然后交由另一个类去组装这些组件。
如何使用?
我们来看一下Android内部关于AlertDialog.Builder的源代码便可以知晓。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112public
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;
}
}
}
现在我们再来看看即P.apply(dialog.mAlert)代码段。我们看看apply函数的实现 。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849public
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);
}
}
}
综上看完上面源码之后我们就可以发现,怪不得我们平时调用对话框的时候可以直接使用,AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);不用Alert.Builder方法创建也可以,因为其本质是一样的,Builder只是把组件的生产过程化成一步步实行而已。这样做有什么实际作用呢?
在Java实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,并且这些资源需要被很多用户反复共享时,就需要使用池。"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能,而在这里AlertDialog.builder就是这个池,修改Builder模式中p.apply(组装)类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
Android开发之Buidler模式初探结合AlertDialog.Builder讲解
最新推荐文章于 2022-04-18 16:29:11 发布