Android Window理解(3.1)---子窗口创建过程:Dialog、PopupWindow

创建子窗口

父子窗口关系标识:

  • View.AttachInfo.mPanelParentWindowToken变量、在ViewRootImpl.setView中设置。

  • Window.mHasChild和Window.mContainer变量、代表Activity所在Window存在父Window。只在TabActivity中使用。

除此之外,对于Dialog等创建的Window为默认类型Application时,会设置Window.token为所在Activity的Window的token,其实就是Activity的token值。

一、Dialog创建过程

Dialog的使用过程,首先构造对象然后调用方法显示。

(1)构造Dialog过程:

1.调用Dialog构造函数传入三个参数context:一般是Activity对应的context,theme:使用的主题id,最后一个是否需要创建ContextThemeWrapper对象,这个对象也是一个壳正在的实现是第一个参数context。

2.构造函数中首先初始化变量mContext,根据传入参数生成或者直接赋值。

3.获取一个WindowManager引用,由于context来自Activity所以这个WM引用就是Activity中的WM对象。

4.生成PhoneWindow对象类型仍然为默认的Application类型,设置Window必要参数,设置回调与Window通信。

5.生成一个Handler处理异步消息回调。

(2)显示Dialog过程:

1.调用show()函数显示Dialog到界面。

2.使用mShowing控制如果已经显示了Dialog,直接设置mDercor可见返回。

3.确保没有显示Dialog,首先回调onCreate()函数,开发者在这个方法中需要调用setContentView()设置Dialog显示的View。接着回调onStart()函数,然后获取开发者设置的View即mDecor。

4.获取Window对应的WIndowManager.LayoutParams参数,最后调用mWindowManager.add()设置显示View,异步回调接口sendShowMessage()。

(3)WindowManager.addView()过程

1.在mWindowManager.addView()内部其实真正是调用mGlobal.addView(view,params,mDisplay,mParentWindow)。因为这个WindowManager来自Activity,所以此方法传入的参数mParentWindow是Activity对于的Window对象。

2.mGlobal.addView()中因为mParentWindow不为空,需要调用mParentWindow.adjustLayoutParamsForSubWindow()设置依附Window的token和title。在该函数中两种处理方式:如果Window类型为子Window则设置其token为父Window对应的DecorView的W对象的Binder引用,如果不是子Window类型设置其token为依附的Activity的token。

3.新建ViewRootImpl对象root,调用root.setView()将Dialog对应的View显示出来。

注意:Dialog对应生成的Window类型仍然为Application。

二、PopupWindow创建显示

PopupWindow内部并不创建Window,而是在Activity的Window基础上添加View。

(1)PopupWindow创建过程

以上是PopupWindow创建过程,存在两种类型构造函数。

对于第一种构造函数主要是以下步骤:

1.赋值Context和WM,因为PopupWindow在Activity中创建所以,以上两个变量均来自Activity内部。所有PopupWindow使用到显示View的Window仍然是Activity的Window对象。

2.获取BackGround的drawable和弹窗动画资源id。

对于这种创建方式需要显式调用setContentView()设置真正显示的View。

对于第二种构造函数:

1.也是赋值Context和WM,和第一种相同。

2.根据传入参数设置显示的View及其高宽和是否获取焦点。

总之,不论是哪种方式都需要设置变量Context和WM。

(2)PopupWindow显示过程

PopupWindow的显示仍然提供两种方式:在指定View下方显示和在指定坐标出显示。

对于第一种在指定View下方显示:

1.首先生成布局参数WindowManager.LayoutParams,设置该参数的type和token,注意此处的type是子类型。

2.准备需要弹出显示的View,这里分为两种情况处理。其一如果是存在background的drawable需要新建一个PopupViewContainer(其实是个FrameLayout)add需要现实的View同时设置背景。其二如果不存在则直接赋值。

3.设置View显示的位置。首先调用findDropDownposition()设置需要显示的位置到布局参数中,接着调用updateAboveAnchor()设置在指定View之上显示时的Drawable。

4.显示View。使用invokePopup()通过WM显示View到指定的位置之下。

对于第二种在指定位置显示其实和第一种步骤相仿,只是在第三步的时候设置View显示的位置时候,直接根据传入参数赋值布局参数即可,其他步骤相同。

注意:PopupWindow通过以上方式创建显示成功,但是仍然不能自动处理系统按键,所有的消息处理必须由mContentView内部去完成。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值