`
huangqinqin
  • 浏览: 359646 次
  • 性别: Icon_minigender_2
  • 来自: 福州
社区版块
存档分类
最新评论

android viewTree and decorView

 
阅读更多

Android ViewTree and DecorView

<!-- .entry-meta -->

The Graphical User Interface forms an integral part of the Android application development. The UI not only acts as a mode of input for the user but also as a mode of feedback from the application based upon an action performed. It is therefore very important that a developer understands how the UI is created and updated.

ViewTree

The basic components of the visual UI is the View and a container called ViewGroup which contains a collection of Views. The ViewGroup itself is an extension of a View. The different widgets like the TextView, Button, etc are nothing but extensions of View which are all arranged within layouts, viz. LinearLayout, RelativeLayout. The layouts are nothing but sub classes of ViewGroup. A ViewTree is nothing but the tree structure that is formed as a collection of these views and viewgroups in a layout.

Let’s start with an example. Here you can see that a number of Views and a LinearLayout are all contained within a RelativeLayout which acts as the parent ViewGroup. All of these come together to form the ViewTree.

The tree structure as seen in Eclipse

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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
  
    <View
        android:id="@+id/WhiteView"
        android:layout_width="200dp"
        android:layout_height="300dp"
        android:layout_marginLeft="20dp"
        android:background="#ffffff" />
  
    <TextView
        android:id="@+id/RedText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/hello"
        android:textColor="#ff0000" />
  
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/GrayView"
        android:layout_alignLeft="@+id/GrayView"
        android:layout_marginBottom="25dp"
        android:background="#0000ff"
        android:orientation="vertical" >
  
        <TextView
            android:id="@+id/GreenText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textColor="#00ff00"
            android:textStyle="bold" />
  
        <Button
            android:id="@+id/Button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button in LinearLayout" />
    </LinearLayout>
      
    <View
        android:id="@+id/RedView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentRight="true"
        android:layout_above="@+id/GrayView"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="-10dp"
        android:background="#ff0000" />
      
    <View
        android:id="@+id/GrayView"
        android:layout_width="200dp"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="20dp"
        android:background="#cccccc" />
  
</RelativeLayout>

When you set the view in your activity using setContentView() and run the program, you’ll see something like this.

If you see the xml file and the way each of the views have been drawn, you’ll observe the following.

  1. The ViewTree that is formed is traversed in a top-down fashion.
  2. The parent is always drawn first and then the children, again in a top-down fashion.

So in our example, the RelativeLayout Layout is first drawn, followed by its children WhiteView, RedText and so on, till finally GrayView is drawn obscuring the Views drawn before.

To visualize, how all the views are being drawn, think of the screen as a coordinate system consisting of X, Y and Z axes and the top-left of the screen as [0,0,0]. X extends to the right, while positive Y extends along the length of the screen. Z extends out of the screen. However do not confuse this system with the coordinate system of the Sensors of the phone.

The View Layout structure and their z-order

So the Views are basically placed along the positive Z axis as we move down the tree. Note that the Android drawing mechanism takes care that it does not draw parts of Views which are hidden by Views placed with greater z-values.

Now that we know how the Views defined by us in the xml are drawn, let us see if this all that there is in the View Tree. For this, we need the help of a tool known as the “heirarchyviewer” in the android installation folder under android-sdk/tools. Before we can use this tool, first run the program in the emulator or the device. Use the commandline to navigate to the folder and start the heirarchyviewer.bat file.

Shown below is the snapshot of the hierarchy viewer.

In the hierarchy viewer, the columns represent the depth of the tree while the number of rows in each column represents the breadth at each level. So you will notice that our RelativeLayout is not really at the root level but is in fact a child of a FrameLayout called “content”. The call to the setContentView(View v) basically sets the View v as the content view.

TreeView heirarchy of an Activity with a TitleBar

Now notice the column containing the FrameLayout “content”. It has a sibling which is another FrameLayout containing a TextView. This is nothing but the Title Bar of the Activity. Let’s see how the View Tree changes if we the titlebar is removed. Go to the manifest file and add the following line to thetag

android:theme="@android:style/Theme.NoTitleBar"

On running the hierarchy viewer, you will notice that the structure has changed. The content view now has just the “content” FrameLayout whose parent is the PhoneWindow$DecorView.

TreeView of the Activity without the TitleBar

Let us take a look at the PhoneWindow and the DecorView.

DecorView

PhoneWindow is the only implementation of the abstract “Window” class which provides the policies defining the look and feel of a window. It forms the top-level window which together with the WindowManager helps in setting the background, title area (either with TitleBar, ActionBar or a user specific custom title bar) and default key processing. The overall window properties can be customized using the WindowManager.LayoutParams.

The DecorView is a private class of the PhoneWindow which is nothing but an extension of FrameLayout. This is the class which forms the top-level application view. Based upon the settings provided in the Android Manifest regarding the themes or the flags set in the PhoneWindow on what type of a window we need to create, the layout of the DecorView is created. So for our example, in the first case, we had a simple theme containing containing a title bar and the contentview. The Phone Window generates a layout that consists of a linearlayout with the title and a framelayout where the contentview can be set. In the second case, we specified that we did not need a titlebar and hence it created the decorview with just the framelayout where the contentview can be set.

Conclusion

So here’s a brief of how the View Tree is generated when a Activity is started,

  1. The PhoneWindow generates a layout for the DecorView which forms the root view based upon the theme provided in the manifest file or otherwise specified using the Window interface.
  2. The activity’s setContentView() is used to set the layout xml as the content view. This internally calls the PhoneWindow’s setContentView().
  3. Now everytime the UI is refreshed the View Tree is traversed as mentioned earlier.

Note: If you plan to use a custom title bar using FEATURE_CUSTOM_TITLE, note that calling setContentView() for the first time or getDecorView() fixes your decorview and you can no longer change many window characteristics. Keep this in mind while designing.

分享到:
评论

相关推荐

    Android View源码解读 DecorView与ViewRootImpl浅谈

    主要解读了Android View源码,为大家详细介绍DecorView与ViewRootImpl,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    Android端投屏demo

    Android手机投屏demo,手机投屏代码实现,需要的拿走。

    Android巧用DecorView实现对话框功能

    其实android的activity界面整个就是一个控件树,DecorView是根节点,DecorView的孩子节点就是一个LinearLayout,这个LinearLayout的孩子系节点就包括状态栏 + 和我们自己写的布局 DecorView是FramLayout的子类...

    Android View 绘制流程(Draw)全面解析

    测量流程决定了View的大小,布局流程决定了View的位置,那么绘制流程将决定View的样子,一个View该显示什么由绘制流程完成。以下源码均取自Android API 21。 从performDraw说起 前面几篇文章提到,三大工作流程始于...

    Android View事件分发机制详解

    准备了一阵子,一直想写一篇事件分发的文章总结一下,这个知识点实在是太重要了。 一个应用的布局是丰富的,有TextView,ImageView,...1. 通过setContentView设置的View就是DecorView的子view,即DecorView是父容器

    android面试题集锦(珍藏)

    事件产生之后首先传递到Activity上面,而Activity接着会传递到 PhoneWindow上,PhoneWindow会传递给RootView,而RootView其实就是DecorView了,接下来便是从 DecorView到View上的分发过程了,具体就可以分成...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    4.1 初识ViewRoot和DecorView 174 4.2 理解MeasureSpec 177 4.2.1 MeasureSpec 177 4.2.2 MeasureSpec和LayoutParams的对应关系 178 4.3 View的工作流程 183 4.3.1 measure过程 183 4.3.2 layout过程 193 ...

    Android View 测量流程(Measure)全面解析

    这里回顾一下上一章所说的内容:DecorView是视图的顶级View,我们添加的布局文件是它的一个子布局,而ViewRootImpl则负责渲染视图,它调用了一个performTraveals方法使得ViewTree开始三大工作流程,然后使得View展现...

    android 截屏

    android 截屏 源码 ,用decorview.getDrawingCache() 方式截屏,与SurfaceControl.screenshot(截取系统屏幕)方式截屏

    Android开发艺术探索

     4.1 初识ViewRoot和DecorView / 174  4.2 理解MeasureSpec / 177  4.2.1 MeasureSpec / 177  4.2.2 MeasureSpec和LayoutParams的对应关系 / 178  4.3 View的工作流程 / 183  4.3.1 measure过程 / 183  4.3.2...

    windowDecorView关系图

    android4.0.1actvity的Window,DecorView之间关系建立过程分析中用到的图

    Android代码-又一个 Material ViewPagerIndicator (指示器)

    ViewPagerIndicator is a @ViewPager.DecorView (like Support-Design's TabLayout and Support-v4's PagerTabStrip and PagerTitleStrip) widgets. Usage is simple - just add it as a child view of your ...

    FloatView:安卓悬浮按钮,依附于decorView不需要各种权限!你懂的!同时支持拖拽,长按事件

    安卓悬浮按钮,依附于decorView不需要各种权限!你懂的!同时支持拖拽,长按事件自动靠边 唯一缺陷在于依附当前activity因此在activity切换的时候会覆盖,但是相比于各种蛋疼的权限 我觉得这点儿是可以接受的 来来来 先...

    Android控件View打造完美的自定义侧滑菜单

    1.对Android中Window类中的DecorView有所了解 2.对Scroller类实现平滑移动效果 3.自定义ViewGroup的实现 首先来看看效果图吧:    下面现在就来说说这里咱们实现侧滑View的基本思路吧,这里我采用的是自定义一个...

    Android代码-EventCollection

    android控件自动化埋点 控件点击事件埋点策略 埋点采用半自动化的方式进行,埋点的界面必须继承自BaseActivity或者BaseFragment ,不含子控件的控件将会自动收集点击事件; 埋点统一收集类名 控件的UI目录树。 需要...

    android的事件分发.wps

    android的事件分发源码分析 我们在一个activity上的控件点击事件中,最先接触事件的使activity 然后时window、decorVIew 首先看activity上的dispatchTouchEvent()方法

    Android代码-GuideView

    方法回调:创建GuideView -- initParams(初始化参数) -- getTargetViewPosition(获取TargetView位置核心方法) -- show(添加GuideView进DecorView) -- addHintView -- GuideView.onMeasure -- GuideView.onLayout -- ...

Global site tag (gtag.js) - Google Analytics