PopupWindow与Dialog的区别


PopupWindow与Dialog的区别

        一、结论
        二、`PopupWindow`与`Dialog`差异演示
        三、`PopupWindow`与`Dialog`的代码实现
            1. 内部实现
            2. 所处的包位置package
            3. 类定义及继承关系
        四、如何选择?

效果上,两者都可以实现弹出界面。本质上有什么区别呢?
一、结论

    PopupWindow为非模态,可以继续操作弹出界面之下的控件;
    Dialog为模态,必须先取消Dialog才能操作Dialog之下的控件;

二、PopupWindow与Dialog差异演示

    PopupWindow操作效果

弹出PopupWindow后,点击“Say Hello“按钮,PopupWindow消失的同时,出现Toast。

说明PopupWindow为非模态。
PopuWindow

    Dialog操作效果

弹出Dialog后,点击"Say Hello"按钮,Dialog消失。再次点击"Say Hello"按钮,出现Toast。

说明Dialog为模态。
Dialog
三、PopupWindow与Dialog的代码实现
1. 内部实现

PopupWindow将PopuDecorView添加到Context的Windowmanager。PopupDecorView继承自FrameLayout。

private class PopupDecorView extends FrameLayout {
}

    1
    2

private void invokePopup(WindowManager.LayoutParams p) {
        if (mContext != null) {
            p.packageName = mContext.getPackageName();
        }

        final PopupDecorView decorView = mDecorView;
        decorView.setFitsSystemWindows(mLayoutInsetDecor);

        setLayoutDirectionFromAnchor();

        mWindowManager.addView(decorView, p);

        if (mEnterTransition != null) {
            decorView.requestEnterTransition(mEnterTransition);
        }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

Dialog创建了PhoneWindow,将PhoneWindow的DecorView添加到Context的WindowManager。

private Activity mOwnerActivity;

private final WindowManager mWindowManager;

final Context mContext;
final Window mWindow;

View mDecor;

private ActionBar mActionBar;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

final Window w = new PhoneWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
w.setOnWindowSwipeDismissedCallback(() -> {
    if (mCancelable) {
        cancel();
    }
});
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

mDecor = mWindow.getDecorView();

if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
    final ApplicationInfo info = mContext.getApplicationInfo();
    mWindow.setDefaultIcon(info.icon);
    mWindow.setDefaultLogo(info.logo);
    mActionBar = new WindowDecorActionBar(this);
}

WindowManager.LayoutParams l = mWindow.getAttributes();
boolean restoreSoftInputMode = false;
if ((l.softInputMode
                & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
            l.softInputMode |=
                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
            restoreSoftInputMode = true;
        }

mWindowManager.addView(mDecor, l);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

2. 所处的包位置package

PopupWindow属于android.widget,与Button,TextView,LinearLayout等控件属于同一个package。

package android.widget;
    PopupWindow
    Button
    TextView
    LinearLayout
    ……

    1
    2
    3
    4
    5
    6

Dialog属于android.app,与Activity属于同一个Package。

package android.app;
    Dialog
    Activity
    ……

    1
    2
    3
    4

3. 类定义及继承关系

PopupWindow继承自Object,并且没有实现任何接口。

public class PopupWindow {
}

    1
    2

Dialog继承自Object,实现了Window.Callback,Window.OnWindowDismissedCallback等接口。

public class Dialog implements
    DialogInterface,
    Window.Callback,
    KeyEvent.Callback,
    OnCreateContextMenuListener,
    Window.OnWindowDismissedCallback {
        
}

    1
    2
    3
    4
    5
    6
    7
    8

Activity的类定义。

public class Activity extends ContextThemeWrapper implements
    LayoutInflater.Factory2,
    Window.Callback,
    KeyEvent.Callback,
    OnCreateContextMenuListener,
    ComponentCallbacks2,
    Window.OnWindowDismissedCallback,
    WindowControllerCallback,
    AutofillManager.AutofillClient {
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

四、如何选择?

优先选择使用Dialog,方便、快速。

需要非模态弹出界面时,使用PopupWindow。

另外PopupWindow提供了定位界面位置的方法,需要设定位置时,考虑使用PopupWindow。
---------------------
作者:济沧海x远沧溟
来源:CSDN
原文:https://blog.csdn.net/chuyangchangxi/article/details/83580702
版权声明:本文为博主原创文章,转载请附上博文链接!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM