view and window简介

来源:互联网 发布:上海微知软件集团 编辑:程序博客网 时间:2024/06/06 03:06

ViewGroup是View的子类,所以它也具有View的特性,但它主要用来充当View的容器,将其中的View视作自己的孩子,对它的子View进行管理,当然它的孩子也可以是ViewGroup类型。

ViewGroup(树根)和它的孩子们(View和ViewGroup)以树形结构形成了一个层次结构,View类有接受和处理消息的功能,android系统所产生的消息会在这些ViewGroup和 View之间传递。

2.          Android的窗口系统
Android的窗口系统是Client/Server模式的,我在这里只讲窗口系统的客户端     我们所提到的概念:View,ViewGroup,DecorView,ViewRoot都是存在于窗口系统的Client端。

Android中的Window是表示Top Level等顶级窗口的概念。DecorView是Window的Top-Level View,这个View可以称之为主View,DecorView会缺省的attach到Activity的主窗口中。

ViewRoot建立了主View(DecorView)与窗口系统Server端的通讯桥梁, ViewRoot是 Handler的子类,即它其实是个Handler,它接受窗口系统服务器端的消息并将消息投递到窗口系统的客户端(图1),然后消息就从客户端的主View往其下面的子View传递,直到消息被完全处理掉为止。

 

public void draw(Canvas canvas)

这个函数用于渲染View和它的孩子,我们不应该在子类对它进行override。

 

ViewGroup介绍
 

ViewGroup继承于View,它可以包含其他的View,就像一个View的容器,我们可以调用其成员函数addView()将View当作孩子放到ViewGroup中。

 

我们经常使用的LinearLayout、relativeLayout等都是ViewGroup的子类,ViewGroup类中有一个内部类ViewGroup.LayoutParams,我们经常使用LayoutParams的子类来构造布局参数。

 

 

//window

         Window 类   位于 /frameworks/base/core/java/android/view/Window.java

            说明:该类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。

  1. public abstract class Window {    
  2.     //...   
  3.     //指定Activity窗口的风格类型   
  4.     public static final int FEATURE_NO_TITLE = 1;  
  5.     public static final int FEATURE_INDETERMINATE_PROGRESS = 5;  
  6.       
  7.     //设置布局文件   
  8.     public abstract void setContentView(int layoutResID);  
  9.   
  10.     public abstract void setContentView(View view);  
  11.   
  12.     //请求指定Activity窗口的风格类型   
  13.     public boolean requestFeature(int featureId) {  
  14.         final int flag = 1<<featureId;  
  15.         mFeatures |= flag;  
  16.         mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;  
  17.         return (mFeatures&flag) != 0;  
  18.     }      
  19.     //...   
  20. }  

PhoneWindow类  位于/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindow.java

         说明: 该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了

            一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是

            把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作

            接口。

  1. public class PhoneWindow extends Window implements MenuBuilder.Callback {  
  2.     //...   
  3.     // This is the top-level view of the window, containing the window decor.  
  4.     private DecorView mDecor;  //该对象是所有应用窗口的根视图 , 是FrameLayout的子类  
  5.       
  6.     //该对象是Activity布局文件的父视图,一般来说是一个FrameLayout型的ViewGroup   
  7.     // 同时也是DecorView对象的一个子视图   
  8.     // This is the view in which the window contents are placed. It is either  
  9.     // mDecor itself, or a child of mDecor where the contents go.  
  10.     private ViewGroup mContentParent;   
  11.       
  12.     //设置标题   
  13.     @Override  
  14.     public void setTitle(CharSequence title) {  
  15.         if (mTitleView != null) {  
  16.             mTitleView.setText(title);  
  17.         }  
  18.         mTitle = title;  
  19.     }  
  20.     //设置背景图片   
  21.     @Override  
  22.     public final void setBackgroundDrawable(Drawable drawable) {  
  23.         if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {  
  24.             mBackgroundResource = 0;  
  25.             mBackgroundDrawable = drawable;  
  26.             if (mDecor != null) {  
  27.                 mDecor.setWindowBackground(drawable);  
  28.             }  
  29.         }  
  30.     }  
  31.     //...       
  32. }  

DecorView类    该类是PhoneWindow类的内部类

         说明: 该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,

            更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及

            TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

  1. private final class DecorView extends FrameLayout {  
  2.     //...   
  3.     //触摸事件处理   
  4.     @Override  
  5.     public boolean onTouchEvent(MotionEvent event) {  
  6.         return onInterceptTouchEvent(event);  
  7.     }  
  8.     //...   
  9. }  

       打个不恰当比喻吧,Window类相当于一幅画(抽象概念,什么画我们未知) ,PhoneWindow为一副齐白石先生的山水画

   (具体概念,我们知道了是谁的、什么性质的画),DecorView则为该山水画的具体内容(有山、有水、有树,各种界面)。

   DecorView呈现在PhoneWindow上。

 

  1. protected ViewGroup generateLayout(DecorView decor) {  
  2.     // Apply data from current theme.   
  3.   
  4.     //...1、根据requestFreature()和Activity节点的android:theme="" 设置好 features值  
  5.       
  6.     //2 根据设定好的 features值,即特定风格属性,选择不同的窗口修饰布局文件  
  7.     int layoutResource;  //窗口修饰布局文件    
  8.     int features = getLocalFeatures();  
  9.     // System.out.println("Features: 0x" + Integer.toHexString(features));  
  10.     if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {  
  11.         if (mIsFloating) {  
  12.             layoutResource = com.android.internal.R.layout.dialog_title_icons;  
  13.         } else {  
  14.             layoutResource = com.android.internal.R.layout.screen_title_icons;  
  15.         }  
  16.         // System.out.println("Title Icons!");  
  17.     } else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0) {  
  18.         // Special case for a window with only a progress bar (and title).  
  19.         // XXX Need to have a no-title version of embedded windows.  
  20.         layoutResource = com.android.internal.R.layout.screen_progress;  
  21.         // System.out.println("Progress!");  
  22.     }   
  23.     //...   
  24.       
  25.     //3 选定了窗口修饰布局文件 ,添加至DecorView对象里,并且指定mcontentParent值  
  26.     View in = mLayoutInflater.inflate(layoutResource, null);  
  27.     decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));  
  28.   
  29.     ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);  
  30.     if (contentParent == null) {  
  31.         throw new RuntimeException("Window couldn't find content container view");  
  32.     }  
  33.   
  34.     if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {  
  35.         ProgressBar progress = getCircularProgressBar(false);  
  36.         if (progress != null) {  
  37.             progress.setIndeterminate(true);  
  38.         }  
  39.     }  
  40.     //...   
  41.     return contentParent;  
  42. }  

 

 1、根据窗口的风格修饰类型为该窗口选择不同的窗口布局文件(根视图)。这些窗口修饰布局文件指定一个用来存放

         Activity自定义布局文件的ViewGroup视图,一般为FrameLayout 其id 为: android:id="@android:id/content"。

        例如窗口修饰类型包括FullScreen(全屏)、NoTitleBar(不含标题栏)等。选定窗口修饰类型有两种:

           ①、指定requestFeature()指定窗口修饰符,PhoneWindow对象调用getLocalFeature()方法获取值;

           ②、为我们的Activity配置相应属性,即android:theme=“”,PhoneWindow对象调用getWindowStyle()方法

              获取值。

        举例如下,隐藏标题栏有如下方法:requestWindowFeature(Window.FEATURE_NO_TITLE);

                   或者 为Activity配置xml属性:android:theme=”@android:style/Theme.NoTitleBar”。

 

        PS:因此,在Activity中必须在setContentView之前调用requestFeature()方法。


 

  确定好窗口风格之后,选定该风格对应的布局文件,这些布局文件位于 frameworks/base/core/res/layout/  ,

        典型的窗口布局文件有:

          R.layout.dialog_titile_icons                          R.layout.screen_title_icons

          R.layout.screen_progress                             R.layout.dialog_custom_title

          R.layout.dialog_title   

          R.layout.screen_title         // 最常用的Activity窗口修饰布局文件

          R.layout.screen_simple    //全屏的Activity窗口布局文件


 

 

原创粉丝点击