分享

Android Dialog的实现分析

 quasiceo 2014-04-12

Android Dialog的实现分析
0

作者:sfshine更新于 05月28日访问(992评论(0

今天来学习一下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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多