[Android] - 对话框的小框架 Managed-Dialog
书里的dialog的那一章 书名 Pro Android 3
在本章,你看到的对话框在Android里是一种特殊的挑战;
我们向您展示了异步对话框的影响
提出了一个抽象的概念,简化管理对话框
开始分析每一个类
IDialogProtocol
这个接口用来管理对话框它的职责包括:
0.1创建对话框 以及任何时候都可以复用它
0.2显示对话框
0.3识别按钮点击
0.4关闭对话框
public interface IDialogProtocol { public int getDialogId();public Dialog create();public void prepare(Dialog dialog);public void show();public void onClickHook(int buttonId);}
ManagedActivityDialog
实现了IDialogProtocol这接口,
template-hook pattern这应该是某种模式,翻译过来叫做 模版挂机模式,我懂的甚少,忘多多指教
它允许派生类有专门的onClickHook方法,负责将show()方法重定向到parent activity
也为show()方法提供了更自然的实现
当对话框完成了点击事件的时候会通知dialogs的parent activity
你可以为你所有新的dialog使用ManagedActivityDialog这个类作为基类
public abstract class ManagedActivityDialogimplements IDialogProtocol,android.content.DialogInterface.OnClickListener{private ManagedDialogsActivity mActivity;private int mDialogId;public ManagedActivityDialog(ManagedDialogsActivity a, int dialogId){mActivity = a;mDialogId = dialogId;}public int getDialogId(){return mDialogId;}public void show(){mActivity.showDialog(mDialogId);}public void onClick(DialogInterface v, int buttonId){ //点击事件onClickHook(buttonId); //按钮的点击事件完毕后通知dialogs的当前activitythis.mActivity.dialogFinished(this, buttonId);}}
DialogRegistry
ManagedDialogsActivity这个类负责两件事
一.保持dialog的ID跟实际的dialog的实例之间的映射,这也就意味着所有调用OnCreate和OnPrepare中特定的dialog 都使用ID-到-对象这样的的映射
二,ManagedDialogsActivity这个Activity使用DialogResistry作为一个仓库来创建注册新的对话框
public class DialogRegistry {SparseArray<IDialogProtocol> idsToDialogs = new SparseArray();public void registerDialog(IDialogProtocol dialog){idsToDialogs.put(dialog.getDialogId(),dialog);}public Dialog create(int id){IDialogProtocol dp = idsToDialogs.get(id);if (dp == null) return null;return dp.create();}public void prepare(Dialog dialog, int id){IDialogProtocol dp = idsToDialogs.get(id);if (dp == null){throw new RuntimeException("Dialog id is not registered:" + id);}dp.prepare(dialog);}}
IDialogFinishedCallBack这个类作为你一系列需要用到对话框的Activity的基类,支持管理对话框动作.
它使一个单实例的DialogRegistry 去跟踪IDialogProtocol确定的所有的managed-dialog
它允许所有派生的Activity通过registerDialog()这个方法来注册它们自己的对话框
transferring the create and prepare semantics tothe respective dialog instance by locating that dialog instance in the dialog registry
上面这句话太长了我翻译不过来,我的理解就是把craete 和prepare正确的转向定位到DialogRegistry中的不同的对话框实例
它还为每一个在DialogRegistry中的dialog提供了回调方法dialogFinished()
public class ManagedDialogsActivity extends Activity implements IDialogFinishedCallBack {//A registry for managed dialogs private DialogRegistry dr = new DialogRegistry(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.registerDialogs(); } protected void registerDialogs() { //不做任何事 //派生类重写此方法 //注册所有的dialog //例 //registerDialog(this.DIALOG_ALERT_ID_D,gmad); } public void registerDialog(IDialogProtocol dialog) { this.dr.registerDialog(dialog); } @Override protected Dialog onCreateDialog(int id) { return this.dr.create(id); } @Override protected void onPrepareDialog(int id, Dialog dialog) { this.dr.prepare(dialog, id); }public void dialogFinished(ManagedActivityDialog dialog, int buttonId){//不需要做任何事//由派生来来重写它}}
IDialogFinishedCallBack让ManagedActivityDialog告诉parent Activity 对话框已经finished了<也就是点了取消或者确定按钮>
这个时候对话框所属的parent activity就可以调用对话框的方法来检索参数
一般情况, ManagedDialogsActivity 实现了这个接口,并且它就是ManagedActivityDialog的parent activity
public interface IDialogFinishedCallBack {public static int OK_BUTTON = -1;public static int CANCEL_BUTTON = -2;public void dialogFinished(ManagedActivityDialog dialog, int buttonId);}
GenericManagedAlertDialog
这是一个AlertDialog的实现,他继承于ManagedActivityDialog这个类
这个类负责使用AlertDialog.Builder来创建实际的警告对话框
它携带了所有它需要的信息作为一个局部变量
因为它只是实现了简单的警告,它的onClickHook()并不需要做任何事
关键的一点是,当你使用这种方法的时候
CenericManagedAlertDialog封装了所有的相关信息在同一个地方
这就使Activity里的主线代码没有太多的瑕疵
public class GenericManagedAlertDialog extends ManagedActivityDialog{private String alertMessage = null;private Context ctx = null;public GenericManagedAlertDialog(ManagedDialogsActivity inActivity, int dialogId, String initialMessage){super(inActivity,dialogId);alertMessage = initialMessage;ctx = inActivity;}public Dialog create(){ AlertDialog.Builder builder = new AlertDialog.Builder(ctx); builder.setTitle("Alert"); builder.setMessage(alertMessage); builder.setPositiveButton("Ok", this ); AlertDialog ad = builder.create(); return ad;}public void prepare(Dialog dialog){ AlertDialog ad = (AlertDialog)dialog; ad.setMessage(alertMessage);}public void setAlertMessage(String inAlertMessage){alertMessage = inAlertMessage;}public void onClickHook(int buttonId){//没事做,无参检索}}
GenericPromptDialog
GenericPromptDialog通过扩展ManagedActivityDialog这个类,封装了一个提示对话框中所有的需求,
并且提供了必要的create() 和prepare()的方法
也可以看到它在局部变量里保存了一个回复文本值,所以它的parent activity就可以在回调方法dialogFinishedcallback中得到它
public class GenericPromptDialog extends ManagedActivityDialog{private String mPromptMessage = null;private View promptView = null;String promptValue = null;private Context ctx = null;public GenericPromptDialog(ManagedDialogsActivity inActivity, int dialogId, String promptMessage){super(inActivity,dialogId);mPromptMessage = promptMessage;ctx = inActivity;}public Dialog create(){ LayoutInflater li = LayoutInflater.from(ctx); promptView = li.inflate(R.layout.promptdialog, null); AlertDialog.Builder builder = new AlertDialog.Builder(ctx); builder.setTitle("prompt"); builder.setView(promptView); builder.setPositiveButton("OK", this); builder.setNegativeButton("Cancel", this); AlertDialog ad = builder.create(); return ad;}public void prepare(Dialog dialog){//nothing for now}public void onClickHook(int buttonId){if (buttonId == DialogInterface.BUTTON1){//ok buttonpromptValue = getEnteredText();}}private String getEnteredText(){EditText et = (EditText)promptView.findViewById(R.id.editText_prompt);String enteredText = et.getText().toString();Log.d("xx",enteredText);return enteredText;}public String getPromptValue(){return this.promptValue;}}
The framework presented here needs to be adjusted somewhat when activities are recreated when the device configuration changes.
The primary change involves recreating dialog objects using the save instance and restore instance methods.
As these dialogs are going to be superceded by fragment based dialogscovered in chapter 29
we haven't provided the necessary changes to persist these dialogs across device configuration changes
上面介绍的框架还需要有所调整,当所有的activity重新创建的时候,以及设备配置又发生了变化的时候;
主要的变化包括重新创建对话框对象,使用保存实例和恢复实例的方法.
这一章节最后的一段话
更多相关文章
- Looper,Handler,Message
- [置顶] Android(安卓)View视图------Android如何创建一个view。
- Android开发注意点
- 第三方应用获得system权限
- Android(安卓)Handler机制之循环消息队列的退出
- Android学习笔记——Activity的四种启动模式
- Android中的Menu(菜单)的三种类型菜单的学习
- Android(安卓)- 事件模型(dispatchTouchEvent , interceptTouchEvn
- Android中Fragment的强大功能