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.
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" ?>
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.
- The ViewTree that is formed is traversed in a top-down fashion.
- 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.
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.
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.
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,
- 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.
- The activity’s setContentView() is used to set the layout xml as the content view. This internally calls the PhoneWindow’s setContentView().
- 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则是连接View与Activity的重要组件。在深入理解View的工作流程,如事件分发、测量、布局和绘制之前,我们需要先探讨Activity如何将UI...
在Android开发中,根View(Root View)是布局文件中最高层次的视图容器,它包含并管理着应用界面中的所有子视图。根View通常是LinearLayout、RelativeLayout、FrameLayout等布局组件,它决定了子视图的排列方式和...
在Android平台上,投屏功能(也称为Mirroring或 casting)是一种允许用户将手机屏幕内容镜像到其他设备,如电视、电脑或投影仪的技术。这个"Android端投屏demo"显然是一个示例项目,用于展示如何在Android应用中实现...
其实android的activity界面整个就是一个控件树,DecorView是根节点,DecorView的孩子节点就是一个LinearLayout,这个LinearLayout的孩子系节点就包括状态栏 + 和我们自己写的布局 DecorView是FramLayout的子类...
在Android应用开发中,`Window`、`Activity`和`DecorView`是三个核心概念,它们之间有着紧密的关系。本文将详细阐述在Android 4.0.1版本中,这三者之间的相互作用以及如何建立联系,同时结合提供的"windowDecorView...
对于顶级View(如DecorView),它的measureSpec在`ViewRootImpl`中确定,基于屏幕的大小和窗口尺寸要求。 4. **父View在measure过程中的作用**:在measure过程中,父View(通常是ViewGroup)扮演关键角色。它会调用...
在Android开发中,View是构建用户界面的基础组件,面试中经常涉及到View的相关问题。本文将深入探讨View的滑动方式、事件分发机制、加载流程以及measure、layout和draw的绘制过程。 1. **View的滑动方式** - `...
在Android应用开发中,View是构建用户界面的基本单元,它构成了复杂的UI系统。理解View的工作原理和相关技术对于开发高效且稳定的App至关重要,也是高级工程师面试的常见考点。以下是对"全面的Android view相关知识...
本篇文章将详细解释如何通过在窗口上添加一层半透明的View来实现Android的夜间模式。 首先,我们要理解Android窗口(Window)的概念。在Android中,每个Activity都与一个Window对应,它是一个抽象层,负责处理显示...
View decorView = activity.getWindow().getDecorView(); decorView.setDrawingCacheEnabled(true); Bitmap bitmap = decorView.getDrawingCache(); ``` 4. **存储截图**:截图的`Bitmap`对象需要保存到本地文件...
- 当用户触摸屏幕时,事件首先被Activity捕获,然后通过`dispatchTouchEvent()`传递给根View(通常是DecorView)。 - 根View接着将其分发给其子View,根据`onInterceptTouchEvent()`的返回值决定是否拦截事件。 -...
本文将深入探讨Android View事件传递机制。 首先,我们从基础开始,Android事件传递主要涉及三个对象:事件(Event)、视图(View)和事件分发链(Event Dispatch Chain)。事件通常由用户的触摸输入触发,如按下、...
在Android中,布局通常由多个View和ViewGroup组成,而Activity则包含一个顶级的DecorView。为了实现滑动退出,我们可以在Activity的根布局上添加一个全屏的透明View(例如使用`FrameLayout`或`RelativeLayout`),这...
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); } } }); ``` 2. **API Level 16 (Jelly Bean) 至 18 (KitKat)** 对于较低版本,没有...
DecorView是窗口的顶级View,整个ViewTree的根节点,它与Activity的主窗口相连。ViewRoot是一个Handler,作为View与WindowManager通信的中介。动画的绘制过程涉及递归地绘制整个窗口,包括绘制背景、可能的层保存、...
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平台上,实现截屏功能...总之,Android截屏功能的实现主要涉及对View的操作,包括获取根View、强制绘制、转换为Bitmap以及保存为文件等步骤。了解这些知识点,可以帮助开发者在自己的应用中轻松添加截屏功能。
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { if ((visibility & View.SYSTEM_UI_...