创建子窗口

父子窗口关系标识:

  • 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内部去完成。

更多相关文章

  1. 踩坑之硬件加速
  2. Android(安卓)手机设置CMWAP 接入点
  3. android_对话框
  4. 【android】为PopupWindow设置动画效果
  5. Android之GridView视图实现
  6. Android动态加载轮播图BannerView
  7. TextView 文本过长时自动打点
  8. android paint画笔 设置透明度setAlpha及 canvas画布
  9. 底部导航栏中间凸出效果

随机推荐

  1. android重启流程
  2. Android(安卓)学习笔记 Contacts (二)Conta
  3. Android(安卓)webkit image的加载过程解
  4. Android支持java8的设置方法
  5. Android(安卓)NDK 是什么
  6. Android中AlertDialog用法实例分析
  7. Android(安卓)动画效果 --Animation 动画
  8. Android执行 shell command
  9. 升级 Android(安卓)Studio 3.2.1 后出现
  10. Android(安卓)调用系统相机 失败