PopupWindow的创建过程
2015-05-29 10:43
387 查看
各位大大我也是初学者,写这些主要是为了对其认识更加清晰,同时也为了以后忘记时可以快速的回忆起。这是我第一次看源码在结合其他大大的思想得到的总结,可能会有很多问题,如果你们发现怎么不对可以告诉我,我很希望能得到你们的评论
这次写这个PopupWindow的创建过程,其实很多地方我也不是很了解。不过我想还是写出来吧,有什么不对的或者哪里不完善的,等学了后面的内容再改吧,到时候新知识结合以前的理解可能会更好的去了解。下面就看看我是怎么理解PopupWindow的创建过程的。
1.通过构造函数创建PopupWindow对象。该对象只是个空壳子。
2.通过setContextView来给弹窗设置弹窗视图组件View
3.通过上面创建的对象中的方法showAsDropDown或showAtLocation来显示该子窗口。这两个方法唯一的区别就是显示的位置不一样,但是其内部的流程是一样的。下面就让我们一起看看showAtLocation这个方法内部实现过程。
public void showAtLocation(IBinder token, int gravity, int x, int y) {
if (isShowing() || mContentView == null) {
return;
}
//1.删除注册的滚动变化监听事件
unregisterForScrollChanged();
mIsShowing = true;
mIsDropdown = false;
//2.创建一个参数token为token的布局
WindowManager.LayoutParams p = createPopupLayout(token);
//3.获取窗口动画资源样式
p.windowAnimations = computeAnimationResource();
//4.创建了一个窗口,并将视图内容加入到里面
preparePopup(p);
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.START;
}
p.gravity = gravity;
p.x = x;
p.y = y;
if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;
//5.将子窗口和父窗口关联,并创建一个RootView,将子窗口和RootView绑定
invokePopup(p);
} 以上就是显示子窗口的过程,大致步骤大家可以看我的代码注释,当我写到这里的时候我突然感觉这个过程和Activity创建的过程是那么的相似。也是首先创建一个空壳对象(activity),然后在创建窗口视图,并将窗口视图和RootView。不同的是创建对象不同,后面都是一样的。但是这里我们发现了没有,PopupWindow是没有自己window对象,这导致PopupWindow是一个纯窗口。因为window有菜单概念,而且还有系统按键,比如“home”,"menu"等。而纯窗口是没有这些的,它所有的用户消息处理的工作都是ViewGroup/View来完成的。对了PopupWindow他是没有自己Context对象的,他的对象就是父视图Activity的Context(注意Dialog是有的)。现在我们在来看看的窗口视图创建的过程。
通过上面代码分析我们可以看出其实创建视图的过程是和Activity相似的,不同的是activity的容器是DectorView, 而PopupWindow是PopupViewContainer 。
最后我们在看下为什么 invokePopup这个方法为什么能将子窗口和父窗口关联,并创建一个RootView,将子窗口和RootView绑定的呢?看下面代码:
private void invokePopup(WindowManager.LayoutParams p) {
if (mContext != null) {
p.packageName = mContext.getPackageName();
}
mPopupView.setFitsSystemWindows(mLayoutInsetDecor);
setLayoutDirectionFromAnchor();
mWindowManager.addView(mPopupView, p);
}
额,限制我明白了 原来他是用了和Activity同一的方法addView。搜嘎。
这次写这个PopupWindow的创建过程,其实很多地方我也不是很了解。不过我想还是写出来吧,有什么不对的或者哪里不完善的,等学了后面的内容再改吧,到时候新知识结合以前的理解可能会更好的去了解。下面就看看我是怎么理解PopupWindow的创建过程的。
1.通过构造函数创建PopupWindow对象。该对象只是个空壳子。
2.通过setContextView来给弹窗设置弹窗视图组件View
3.通过上面创建的对象中的方法showAsDropDown或showAtLocation来显示该子窗口。这两个方法唯一的区别就是显示的位置不一样,但是其内部的流程是一样的。下面就让我们一起看看showAtLocation这个方法内部实现过程。
public void showAtLocation(IBinder token, int gravity, int x, int y) {
if (isShowing() || mContentView == null) {
return;
}
//1.删除注册的滚动变化监听事件
unregisterForScrollChanged();
mIsShowing = true;
mIsDropdown = false;
//2.创建一个参数token为token的布局
WindowManager.LayoutParams p = createPopupLayout(token);
//3.获取窗口动画资源样式
p.windowAnimations = computeAnimationResource();
//4.创建了一个窗口,并将视图内容加入到里面
preparePopup(p);
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.START;
}
p.gravity = gravity;
p.x = x;
p.y = y;
if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;
//5.将子窗口和父窗口关联,并创建一个RootView,将子窗口和RootView绑定
invokePopup(p);
} 以上就是显示子窗口的过程,大致步骤大家可以看我的代码注释,当我写到这里的时候我突然感觉这个过程和Activity创建的过程是那么的相似。也是首先创建一个空壳对象(activity),然后在创建窗口视图,并将窗口视图和RootView。不同的是创建对象不同,后面都是一样的。但是这里我们发现了没有,PopupWindow是没有自己window对象,这导致PopupWindow是一个纯窗口。因为window有菜单概念,而且还有系统按键,比如“home”,"menu"等。而纯窗口是没有这些的,它所有的用户消息处理的工作都是ViewGroup/View来完成的。对了PopupWindow他是没有自己Context对象的,他的对象就是父视图Activity的Context(注意Dialog是有的)。现在我们在来看看的窗口视图创建的过程。
private void preparePopup(WindowManager.LayoutParams p) { if (mContentView == null || mContext == null || mWindowManager == null) { throw new IllegalStateException("You must specify a valid content view by " + "calling setContentView() before attempting to show the popup."); } if (mBackground != null) { final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); int height = ViewGroup.LayoutParams.MATCH_PARENT; if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { height = ViewGroup.LayoutParams.WRAP_CONTENT; } //1.创建一个容器(窗口视图),这个容器是用来装载通过上面setContextView设置的视图。 //其实这个容器就是FrameLayout的子类,而FrameLayout又是ViewGroup的子类 PopupViewContainer popupViewContainer = new PopupViewContainer(mContext); PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height ); popupViewContainer.setBackgroundDrawable(mBackground); //2.将视图组件mContentView装到容器popupViewContainer中 popupViewContainer.addView(mContentView, listParams); mPopupView = popupViewContainer; } else { mPopupView = mContentView; } mPopupViewInitialLayoutDirectionInherited = (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); mPopupWidth = p.width; mPopupHeight = p.height; }
通过上面代码分析我们可以看出其实创建视图的过程是和Activity相似的,不同的是activity的容器是DectorView, 而PopupWindow是PopupViewContainer 。
最后我们在看下为什么 invokePopup这个方法为什么能将子窗口和父窗口关联,并创建一个RootView,将子窗口和RootView绑定的呢?看下面代码:
private void invokePopup(WindowManager.LayoutParams p) {
if (mContext != null) {
p.packageName = mContext.getPackageName();
}
mPopupView.setFitsSystemWindows(mLayoutInsetDecor);
setLayoutDirectionFromAnchor();
mWindowManager.addView(mPopupView, p);
}
额,限制我明白了 原来他是用了和Activity同一的方法addView。搜嘎。
相关文章推荐
- android教程之使用popupwindow创建菜单示例
- android PopupWindow 和 Activity弹出窗口实现方式
- Android PopupWindow 点击外面取消实现代码
- android自定义popupwindow仿微信右上角弹出菜单效果
- Android中PopupWindow响应返回键并关闭的2种方法
- Android入门之PopupWindow用法实例解析
- android popwindow实现左侧弹出菜单层及PopupWindow主要方法介绍
- 一段android跳转到web界面的代码
- pthread_join()和pthread_detach()代码分析
- PopupWindow gridview 无法响应Item
- 如何提升COBOL系统代码分析效率
- PopupWindow 实现 弹出后 其余部分变灰(类似dialog)
- 一个简单的PopupWindow做的选项菜单点击按钮会在按钮下弹出几个下拉控件
- PopupWindow的使用
- PopupWindow(第一篇CSDN博客,希望能坚持写下去,也希望大家多多支持)
- 学习计划
- 单元测试总结
- C++高效程序设计
- CALL是如何炼成的之理论篇
- Google Android开发入门与实战