Android WindowManagerService解析(4)
来源:互联网 发布:淘宝模特余露工作室 编辑:程序博客网 时间:2024/06/07 14:36
看篇文章之前,建议先看看前面几篇,这样理解会更深刻,下面我们来看看PopupWindow的显示过程
一、PopupWindow的创建
public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { mContext = context; // 得到一个WindowManager对象 mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);}
二、setContentView
public void setContentView(View contentView) { if (isShowing()) { return; } mContentView = contentView; if (mContext == null && mContentView != null) { mContext = mContentView.getContext(); } if (mWindowManager == null && mContentView != null) { mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); }}
就是将contentView赋值给成员变量mContentView,并且确保mWindowManager对象不为null。
三、显示过程
我们这里以showAtLocation函数为例,进行查看
public void showAtLocation(IBinder token, int gravity, int x, int y) { if (isShowing() || mContentView == null) { return; } unregisterForScrollChanged(); mIsShowing = true; mIsDropdown = false; // 1、获取布局属性 WindowManager.LayoutParams p = createPopupLayout(token); p.windowAnimations = computeAnimationResource(); // 2、做一些准备工作 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; // 3、进行显示 invokePopup(p);}
从前面的分析我们知道,WindowManager添加一个view需要两个参数,一个是需要添加的view对象,一个是布局属性,在前面的setContent函数已经给出了需要添加的view了,对于布局属性就在createPopupLayout函数中生成。
private WindowManager.LayoutParams createPopupLayout(IBinder token) { WindowManager.LayoutParams p = new WindowManager.LayoutParams(); p.gravity = Gravity.START | Gravity.TOP; p.width = mLastWidth = mWidth; p.height = mLastHeight = mHeight; if (mBackground != null) { p.format = mBackground.getOpacity(); } else { p.format = PixelFormat.TRANSLUCENT; } p.flags = computeFlags(p.flags); p.type = mWindowLayoutType; p.token = token; p.softInputMode = mSoftInputMode; p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); return p;}
下面看看显示过程,其实猜都可以猜到,我们的view以及该view对应的布局属性已经准备好了,下面就是直接调用windowManager的addView方法,下面我们看看invokePopup函数。
private void invokePopup(WindowManager.LayoutParams p) { if (mContext != null) { p.packageName = mContext.getPackageName(); } mPopupView.setFitsSystemWindows(mLayoutInsetDecor); setLayoutDirectionFromAnchor(); mWindowManager.addView(mPopupView, p);}
这里看到使用的是mPopupView,但是在前面setContentView中设置的是mContentView,其实mPopupView对应的就是mContentView,它的赋值操作在preparePopup函数中。
private void preparePopup(WindowManager.LayoutParams p) { 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; } // when a background is available, we embed the content view // within another view that owns the background drawable PopupViewContainer popupViewContainer = new PopupViewContainer(mContext); PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height ); popupViewContainer.setBackgroundDrawable(mBackground); popupViewContainer.addView(mContentView, listParams); mPopupView = popupViewContainer; } else { mPopupView = mContentView; } mPopupViewInitialLayoutDirectionInherited = (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); mPopupWidth = p.width; mPopupHeight = p.height;}
这里对mContentView做了一些处理然后赋值给了mPopupView。
从这里我们可以看到,对应界面的显示,其实思路都是一样的,都是使用的WindowManager,也就是说WindowManagerService对我们所有的UI会进行管理。
阅读全文
0 0
- Android WindowManagerService解析(4)
- Android WindowManagerService解析(1)
- Android WindowManagerService解析(2)
- Android WindowManagerService解析(3)
- Android WindowManagerService解析(5)
- Android WindowManagerService解析(6)
- Android解析WindowManagerService(一)WMS的诞生
- Android WindowManagerService
- Android WindowManagerService
- Android解析WindowManagerService(二)WMS的重要成员和Window的添加过程
- android WindowManagerService addFakeWindow 研究
- Android按键消息传播流程(WindowManagerService.java)
- Android按键消息传播流程(WindowManagerService.java)
- Android WindowManagerService机制分析(一):窗口的显示层级
- WindowManagerService
- Android WindowManagerService相关的Session
- Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- C语言实验——圆周率
- Docker报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
- 分布式PRC服务框架Dubbo
- 可变类和不可变类(Mutable and Immutable Objects) 1. 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当你获得这个
- mongoDB3.4主从复制实现(第一种情况亲测)
- Android WindowManagerService解析(4)
- mysql多表更新的问题
- 歌单
- java学习之接口
- 前端
- mysql 查询去除表中(多个条件确定的一个数据)
- 50585505
- Excel在统计分析中的应用—第八章—假设检验-方差已知下总体均值的单侧检验
- tcp、udp、socket,关系