今天来学习一下Android dialog
我们做事情 一定要知其然 并且知其所以然 就先来看看Android Dialog是如何实现的 这可以避免一下同学在使用dialog的误区哦
那么我们一般是这样创建一个Dialog的
1 2 3 | final Dialog dialog = new Dialog(this, R.style.Translucent_NoTitle); dialog.setContentView(R.layout.common_dialog); dialog.show(); |
ok 让我们去RTFSC吧
看Dialog的构造函数```java
Dialog(Context context, int theme, boolean createContextWrapper) {
if (theme == 0) {
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
outValue, true);
theme = outValue.resourceId;
}
1 2 3 4 5 6 7 8 9 | mContext = createContextWrapper ? new ContextThemeWrapper(context, theme) : context; mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); Window w = PolicyManager.makeNewWindow(mContext); mWindow = w; w.setCallback(this); w.setWindowManager(mWindowManager, null, null); w.setGravity(Gravity.CENTER); mListenersHandler = new ListenersHandler(this); } |
1 2 3 4 5 | 原来是一个初始化了一个window 和一个 windowmanager 然后在setContentView代码中:```java public void setContentView(int layoutResID) { mWindow.setContentView(layoutResID); } |
是让window设置指定的layout ok 这样就可以把他适时的show出来了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /** * Start the dialog and display it on screen. The window is placed in the * application layer and opaque. Note that you should not override this * method to do initialization when the dialog is shown, instead implement * that in {<a href=""http://www./home.php?mod=space&uid=91636"" target=""_blank"">@link</a> #onStart}. */ public void show() { if (mShowing) { if (mDecor != null) { if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) { mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR); } mDecor.setVisibility(View.VISIBLE); } return; } mCanceled = false; if (!mCreated) { dispatchOnCreate(null); } onStart(); mDecor = mWindow.getDecorView(); if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) { mActionBar = new ActionBarImpl(this); } WindowManager.LayoutParams l = mWindow.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) { WindowManager.LayoutParams nl = new WindowManager.LayoutParams(); nl.copyFrom(l); nl.softInputMode |= WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; l = nl; } try { mWindowManager.addView(mDecor, l); mShowing = true; sendShowMessage(); } finally { } } |
注释说的很明白 其实是在当前Activity添加了一个window 如果是第一次show会 mDecor = mWindow.getDecorView(); 这个mDecor就是那个dialog了
他会被增加到windowmanager中 mWindowManager.addView(mDecor, l); 就显示出来了
那么我们就知道 他的hide就是让他gone 那么dismiss就是 mWindowManager.removeView(mDecor);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public void hide() { if (mDecor != null) { mDecor.setVisibility(View.GONE); } } ``````java void dismissDialog() { if (mDecor == null || !mShowing) { return; } if (mWindow.isDestroyed()) { Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!"); return; } try { mWindowManager.removeView(mDecor); } finally { if (mActionMode != null) { mActionMode.finish(); } mDecor = null; mWindow.closeAllPanels(); onStop(); mShowing = false; sendDismissMessage(); } } |
说这么多可不是废话 从中我们看出 Android dialog是往Activity上通过windowmanager 往上面贴window 而显示出来的dialog 那么
除了一些特殊情况 是不是我们应该摒弃为了显示一个dialog而生成一个Activity的情况呢 (就是dialogActivity)
然后还要介绍一个 AlertDialog.Builder 的东西 这个东西和Dialog那真是息息相关啊 他是个什么东西 就是一个Builder呗? 不知道什么意思? 你英语老师是谁?```java
Builder dialog = new AlertDialog.Builder(context);
dialog.show();
1 2 3 4 5 6 7 | 这两句话是builder的核心代码了 看他的构造函数```java public Builder(Context context, int theme) { P = new AlertController.AlertParams(new ContextThemeWrapper( context, resolveDialogTheme(context, theme))); mTheme = theme; } |
额。只是设置一下参数而已啊。这怎么可以?dialog呢?
继续往下看```java
public AlertDialog show() {
AlertDialog dialog = create();
dialog.show();
return dialog;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ```java public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false); 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; } |
奥 明白了把?是应该叫builder吧?
这里说明一点 AlertDialog继承自Dialog 实现了一些 添加各种yes no button的封装 所以如果不定义dialog 一般都使用这个东西和builder