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
版权声明:本文为博主原创文章,转载请附上博文链接!