android分析windowManager、window、viewGroup

本文将主要介绍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 classLocalWindowManager 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是否已经包含到一个父容器中

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

                3.调用addInArray来添加View

                4.设置父View为当前的ViewGroup

                5.焦点的处理

                6.当前View的AttachInfo信息

                7.View树改变的监听

                8.子View中的mViewFlags的设置

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);

1.对于type :

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

对于windowAnimation

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

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

  <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,死也看得不到动画效果滴。
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值