Window、View与setContentView()

来源:互联网 发布:ubuntu lamp的安装 编辑:程序博客网 时间:2024/06/07 14:28

只要你使用过Activity,那么你一定使用过setContentView这个方法。一般都是这样调用该方法:

  1. setContentView(R.layout.main);  

然后,在手机或者模拟器上就可以看见自己的布局。

如果,你留意的话,setContentView还有很多过载方法:

  1. public void setContentView(int layoutResID) {  
  2.     getWindow().setContentView(layoutResID);  
  3. }  
  4.   
  5. public void setContentView(View view) {  
  6.     getWindow().setContentView(view);  
  7. }  
  8.   
  9. public void setContentView(View view, ViewGroup.LayoutParams params) {  
  10.     getWindow().setContentView(view, params);  
  11. }  

那么,getWindow()方法是做什么的呢?一探究竟:

  1. public Window getWindow() {  
  2.         return mWindow;  
  3. }  

可以看出,该方法返回一个Window实例。但是Window是一个抽象类啊,怎么可以有实例对象???

为了解决这个问题,可以看看Window类的说明:

  1. Class Overview  
  2.   
  3. Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.  
  4.   
  5. The only existing implementation of this abstract class is android.policy.PhoneWindow, which you should instantiate when needing a Window. Eventually that class will be refactored and a factory method added for creating Window instances without knowing about a particular implementation.  

原来,Window类有一个子类PhoneWindow,那么如何得知getWindow返回的是PhoneWindow实例呢?来,看下面这张图:

如果,有兴趣的话,您可以参照源码看看。关于PhoneWindow这个类在下载的sdk的api中没有说明。

至此,您应该明白setContentView()方法是调用PhoneWindow类的同名方法。源码如下:

  1. @Override  
  2.     public void setContentView(int layoutResID) {  
  3.         if (mContentParent == null) {  
  4.             installDecor();  
  5.         } else {  
  6.             mContentParent.removeAllViews();  
  7.         }  
  8.         mLayoutInflater.inflate(layoutResID, mContentParent);  
  9.         final Callback cb = getCallback();  
  10.         if (cb != null) {  
  11.             cb.onContentChanged();  
  12.         }  
  13.     }  
  14.   
  15.     @Override  
  16.     public void setContentView(View view) {  
  17.         setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));  
  18.     }  
  19.   
  20.     @Override  
  21.     public void setContentView(View view, ViewGroup.LayoutParams params) {  
  22.         if (mContentParent == null) {  
  23.             installDecor();  
  24.         } else {  
  25.             mContentParent.removeAllViews();  
  26.         }  
  27.         mContentParent.addView(view, params);  
  28.         final Callback cb = getCallback();  
  29.         if (cb != null) {  
  30.             cb.onContentChanged();  
  31.         }  
  32.     }  

更多源码,参看android源码。

每个Activity都会实例化一个Window并且只有一个,而View就像是贴在Window上的装饰品。窗户(Window)只有一个,但是窗花(View)可以有很多。

关于PhoneWindow的其它内容,可以看看LayoutInflater基础。


转载地址:http://www.cnblogs.com/tangchenglin/archive/2011/12/14/2287567.html