本文将主要介绍addview方法,在windowManager、window、viewGroup中的实现原理。首先将介绍这些类结构关系,然后分析其内在联系,介绍实现原理,最后介绍重要的一个参数windowManager.layoutParams。

文章预计分为三个部分。

一、首先介绍一下上述接口、类的结构

  接口:windowManager

    用来在应用与window之间的管理接口,管理窗口顺序,消息等

public interface WindowManager extends android.view.ViewManager

抽象类:window

    定义窗口样式和行为的抽象基类,用于作为顶层的view加到windowManager中。

    唯一实现了这个抽象类的是PhoneWindow,实例化PhoneWindow需要一个窗口

    public abstract class Window

    其中有一个很重要的内部类

    private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper{...};

  

  抽象类:viewGroup

    包含其他view的容器,layouts和view 容器的基类。

    public abstract class ViewGroup extends View implements ViewParent, ViewManager

  

  相关接口:ViewParent

        定义了一个view parent 的要负责的功能以及view和parent view之间的关联

    public interface ViewParent {

         public void requestLayout();

        public void createContextMenu(ContextMenu menu);

        public void bringChildToFront(View child);

        .....

    }

    viewManager

      用来添加和移除activity中的view的接口

public interface ViewManager
{
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

二.他们之间的内在关系。

  1. 对于view来说,添加到viewGroup中是通过addView();方式来实现的,在addView中实际上使用的是:

            addViewInner(child, index, params, false);

           流程是: 1.首先是对子View是否已经包含到一个父容器中

                2.对子View布局参数的处理

                3.调用addInArray来添加View

                4.设置父View为当前的ViewGroup

                5.焦点的处理

                6.当前View的AttachInfo信息

                7.View树改变的监听

                8.子View中的mViewFlags的设置

主要是通过    addInArray添加view,添加的实现为system.arrayCopy(....);

  

  2. 对于viewGroup来说,都会显示在在一个窗口中,每个都有一个父节点mParent,,最顶上的节点也是一个viewGroup,也就是decorView。

  对于每个activity只有一个decorView也就是ViewRoot,只有一个window,window的获取是通过下面方法获取的。

1
Window mWindow = PolicyManager.makeNewWindow(this);

  在activity中使用setContentView(),其实是使用了 window.setContentView()完成的,window.setcontentView,

  还是通过LocalWindowManager.addView(view, params)来实现的。这里LocalWindowManager是实现了WindowManagerImpl.CompatModeWrapper

  ,本质上就是WindowManager、viewManager接口中的addvidew方法。

  

  3.  对于windowManager来说一个系统只有一个,它是由系统底层实现的,用于负责调度当前显示那个窗口,消息处理我们获得一个windowManager的方式如下:

  

1
2
3
WindowManager windowManager = (WindowManager)context().getSystemService(
                                    Context.WINDOW_SERVICE);

  这里windowManager其实是一个接口,而通过getSystemService的方式。通过这个方式可以获取很多的系统服务,比如电话、闹钟、电源管理等等。

  同时windowManager和几个类之间的内在联系如下:

本节结束,下节讲述windowManager中WindowManager.layoutParams相关。

三.接上一节,分析windowManager中添加一个悬浮框的方式,首先看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
WindowManager.LayoutParams params = new LayoutParams();
        params.width = width;
        params.height = height;
        params.format = PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;//后面窗口仍然可以处理点设备事件
        params.setTitle("Toast");
        params.gravity = gravity;
        params.windowAnimations = styleAnimations;
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
TextView float = new TextView(context);
float.settext("this is a float window ");
windowManager.addView(view, this.mLayoutParams);

    params中一般参数都容易理解,这里有几个特别要注意的地方:type、flags、windowAnimation

   1.对于type :

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
type 的取值:
      应用程序窗口。
      public static final int FIRST_APPLICATION_WINDOW = 1;   
      所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。    
      public static final int TYPE_BASE_APPLICATION   =1;
        
      普通应用功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。
      public static final int TYPE_APPLICATION       = 2;
       用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。
      它用于让系统显示些信息,直到应用程序可以开启自己的窗口。  
      public static final int TYPE_APPLICATION_STARTING = 3;
      
      应用程序窗口结束。
      public static final int LAST_APPLICATION_WINDOW = 99;
      子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。
      public static final int FIRST_SUB_WINDOW       = 1000;
      面板窗口,显示于宿主窗口上层。
      public static final int TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW;
      媒体窗口,例如视频。显示于宿主窗口下层。
      public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;
      应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
      public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2;
      对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
      public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3;
      媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕)
      public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW +4;
      子窗口结束。( End of types of sub-windows )
      public static final int LAST_SUB_WINDOW        = 1999;
      系统窗口。非应用程序创建。
      public static final int FIRST_SYSTEM_WINDOW    = 2000;
      状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。
      public static final int TYPE_STATUS_BAR        =  FIRST_SYSTEM_WINDOW;
      搜索栏。只能有一个搜索栏;它位于屏幕上方。
      public static final int TYPE_SEARCH_BAR        = FIRST_SYSTEM_WINDOW+1;
      电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
      public static final int TYPE_PHONE            = FIRST_SYSTEM_WINDOW+2;
      系统提示。它总是出现在应用程序窗口之上。
      public static final int TYPE_SYSTEM_ALERT      =  FIRST_SYSTEM_WINDOW +3;
      锁屏窗口。
      public static final int TYPE_KEYGUARD          = FIRST_SYSTEM_WINDOW +4;
      信息窗口。用于显示toast。
      public static final int TYPE_TOAST            = FIRST_SYSTEM_WINDOW +5;
      系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
      public static final int TYPE_SYSTEM_OVERLAY    =  FIRST_SYSTEM_WINDOW +6;
      电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
      public static final int TYPE_PRIORITY_PHONE    =  FIRST_SYSTEM_WINDOW +7;
      系统对话框。(例如音量调节框)。
      public static final int TYPE_SYSTEM_DIALOG     =  FIRST_SYSTEM_WINDOW +8;
      锁屏时显示的对话框。
      public static final int TYPE_KEYGUARD_DIALOG   =  FIRST_SYSTEM_WINDOW +9;
      系统内部错误提示,显示于所有内容之上。
      public static final int TYPE_SYSTEM_ERROR      =  FIRST_SYSTEM_WINDOW +10;
      内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。
      public static final int TYPE_INPUT_METHOD      =  FIRST_SYSTEM_WINDOW +11;
      内部输入法对话框,显示于当前输入法窗口之上。
      public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW +12;
      墙纸窗口。
      public static final int TYPE_WALLPAPER         = FIRST_SYSTEM_WINDOW +13;
      状态栏的滑动面板。
      public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW +14;
      系统窗口结束。
<br>      public static final int LAST_SYSTEM_WINDOW     = 2999;

  这里需要注意的地方是:

  对于需要依附于activity的选择2000以下的,独立于activity,使用2002

  

2.对于flag,这里详细的说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int FLAGS_CHANGED  
int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON Window flag: as long as this window is visible to the user, allow the lock screen to activate while the screen is on.
int FLAG_ALT_FOCUSABLE_IM   Window flag: invert the state of FLAG_NOT_FOCUSABLE with respect to how this window interacts with the current method.
int FLAG_BLUR_BEHIND     This constant was deprecated in API level 14. Blurring is no longer supported.
int FLAG_DIM_BEHIND Window flag: everything behind this window will be dimmed.
int FLAG_DISMISS_KEYGUARD   Window flag: when set the window will cause the keyguard to be dismissed, only if it is not a secure lock keyguard.
int FLAG_DITHER  This constant was deprecated in API level 17. This flag is no longer used.
int FLAG_FORCE_NOT_FULLSCREEN   Window flag: override FLAG_FULLSCREEN and force the screen decorations (such as the status bar) to be shown.
int FLAG_FULLSCREEN Window flag: hide all screen decorations (such as the status bar) while this window is displayed.
int FLAG_HARDWARE_ACCELERATED  
Indicates whether this window should be hardware accelerated.
int FLAG_IGNORE_CHEEK_PRESSES   Window flag: intended for windows that will often be used when the user is holding the screen against their face, it will aggressively filter the event stream to prevent unintended presses in this situation that may not be desired for a particular window, when such an event stream is detected, the application will receive a CANCEL motion event to indicate this so applications can handle this accordingly by taking no action on the event until the finger is released.
int FLAG_KEEP_SCREEN_ON Window flag: as long as this window is visible to the user, keep the device's screen turned on and bright.
int FLAG_LAYOUT_INSET_DECOR Window flag: a special option only for use in combination with FLAG_LAYOUT_IN_SCREEN.
int FLAG_LAYOUT_IN_OVERSCAN Window flag: allow window contents to extend in to the screen's overscan area, if there is one.
int FLAG_LAYOUT_IN_SCREEN   Window flag: place the window within the entire screen, ignoring decorations around the border (such as the status bar).
int FLAG_LAYOUT_NO_LIMITS   Window flag: allow window to extend outside of the screen.
int FLAG_NOT_FOCUSABLE  Window flag: this window won't ever get key input focus, so the user can not send key or other button events to it.
int FLAG_NOT_TOUCHABLE  Window flag: this window can never receive touch events.
int FLAG_NOT_TOUCH_MODAL    Window flag: even when this window is focusable (its FLAG_NOT_FOCUSABLE is not set), allow any pointer events outside of the window to be sent to the windows behind it.
int FLAG_SCALED Window flag: a special mode where the layout parameters are used to perform scaling of the surface when it is composited to the screen.
int FLAG_SECURE Window flag: treat the content of the window as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays.
int FLAG_SHOW_WALLPAPER Window flag: ask that the system wallpaper be shown behind your window.
int FLAG_SHOW_WHEN_LOCKED   Window flag: special flag to let windows be shown when the screen is locked.
int FLAG_SPLIT_TOUCH    Window flag: when set the window will accept for touch events outside of its bounds to be sent to other windows that also support split touch.
int FLAG_TOUCHABLE_WHEN_WAKING  Window flag: when set, if the device is asleep when the touch screen is pressed, you will receive this first touch event.
int FLAG_TURN_SCREEN_ON Window flag: when set as a window is being added or made visible, once the window has been shown then the system will poke the power manager's user activity (as if the user had woken up the device) to turn the screen on.
int FLAG_WATCH_OUTSIDE_TOUCH    Window flag: if you have set FLAG_NOT_TOUCH_MODAL, you can set this flag to receive a single special MotionEvent with the action MotionEvent.ACTION_OUTSIDE for touches that occur outside of your window.

  3.对于windowAnimation

  很多人说为什么我设置了windowAnimation,但是没有动画效果呢?

这里一定要注意,这里需要使用style,在style中添加如下:

1
2
3
4
5
6
7
  <style name="top">
    <item name="@android:windowEnterAnimation">@anim/sanqiwan_toast_slide_top_enter</item>
   <item name="@android:windowExitAnimation">@anim/sanqiwan_toast_slide_top_exit</item>
</style>

  然后将style的resourceId赋给params.windowAnimation,如果是将动画的resourceId赋值给params.windowAnimation,死也看得不到动画效果滴。

欢迎转载,请标明出处。

android分析windowManager、window、viewGroup之间关系相关推荐

  1. android 行高和字号之间关系,字号与行高

    1. 什么是字号与行高 什么是字号大小?字号大小就是字体的高度,例如设置字号为50px,那么它的高度如下图所示: 什么是行距呢?如下图所示: 其中半行距 = (lineHeight – fontSiz ...

  2. android 行高和字号之间关系,行高和字号

    行高:指的是每一行的高度 盒子高:指的是元素的高度 1.文字默认在行高中默认是居中显示的 2.如果盒子中只有一行内容,要让这一行内容居中,只需要设置行高=盒子高度(line-height = 盒子高度 ...

  3. Android事件分发之ViewGroup篇 -- ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系

    Android事件分发之ViewGroup篇(FatherViewGroup) – ViewGroup的dispatchTouchEvent.onTouchEvent.onInterceptTouch ...

  4. 一篇文章看明白 Android 图形系统 Surface 与 SurfaceFlinger 之间的关系

    Android - SurfaceFlinger 图形系统 相关系列 一篇文章看明白 Android 系统启动时都干了什么 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制 一篇文 ...

  5. 理清Activity、View及Window之间关系

    我的简书同步发布:理清Activity.View及Window之间关系 转载请注明出处:[huachao1001的专栏:http://blog.csdn.net/huachao1001] View.W ...

  6. Android解析WindowManager(二)Window的属性

    相关文章 Android系统启动系列 Android深入四大组件系列 Android解析WindowManager系列 前言 在上一篇文章我们学习了WindowManager体系,了解了Window和 ...

  7. Android中的Window、WindowManager以及悬浮框视频播放的实现

    摘要:近日看公司直播项目,其中有一个功能就是退出某房间之后,直播界面会以悬浮窗的形式出现,并且可以拖动悬浮窗到界面中任意位置,点击悬浮框之后,又可以回到房间中继续观看直播.现在这个功能在主流的直播或者 ...

  8. 【机器学习】逻辑回归案例一:保险与年龄之间关系分析

    逻辑回归案例一:保险与年龄之间关系分析 逻辑回归案例一:保险与年龄之间关系分析 1 数据加载 2 数据切分 3 模型创建与应用 4 逻辑回归和线性回归关系 手动反爬虫,禁止转载: 原博地址 https ...

  9. Android系统服务-WindowManager

    WindowManager是Android中一个重要的服务 (Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的各个 ...

最新文章

  1. 正则的实例用法,删除包含某些字符的字符串
  2. mac、linux 查看端口占用程序
  3. DevExpress 控件使用之GridControl基本属性设置
  4. Linux 文件和目录的属性及权限
  5. c语言点阵字符,点阵的汉字程序
  6. 4 Convex optimization problems
  7. 机器学习速成课程 | 练习 | Google Development——编程练习:使用 TensorFlow 的起始步骤
  8. 快速排序图解_排序算法
  9. 冻库正常低压力是多少_弹涂鱼上市卖不动,还有8万斤要进冻库,市场低迷,不值钱了...
  10. python爬虫简单实例
  11. 通过银行卡号获取所属银行「支付宝」
  12. 正交表测试与混合正交表工具
  13. Unity 讯飞实时语音转写(三)—— 分析转写结果
  14. 单三相STS电能表 键盘表 代码表 预付费表 非洲 东南亚 分体式电表方案
  15. 华为太极magisk安装教程_【玩机必会技能】小米手机通用刷TWRP RECOVERY|ROOT|刷第三方ROM教程...
  16. 给微信小程序配一个App如何?
  17. 【python学习】自定义三维向量类 加减乘除查看值和长度
  18. 高中数学基础10:二项分布与二项式定理
  19. php怎么魔方加密,深度解析php混淆加密解密的手段,希望对大家解读魔方加密有所帮助 [tihuan]...
  20. 网工四年路:从小工厂到外资银行

热门文章

  1. 【Android 应用开发】Activity 返回堆栈管理 ( 栈内复用模式 singleTask | 单实例模式 singleInstance )
  2. vue-cli2.0创建项目步骤
  3. Python脚本--微信公众号自定义菜单的创建及获取
  4. 二周第三次课(3月28日)
  5. 洛谷 1195 口袋的天空
  6. 转载:VMware workstation创建虚拟机,安装Ubuntu系统
  7. 关于CSS中的字体尺寸设置 em rem等
  8. 实验中遇到的Quartus II的Warning的解释、原因以及解决方法
  9. 线程的切入和切出(切入: 一个线程被系统选中占用处理器开始或继续运行)
  10. HTTP协议常用标准状态码含义