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