Android原理View、ViewGroup
Android的UI界面都是由View和ViewGroup及其派生类组合而成的。其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的。AndroidUI界面的一般结构可参见下面的示意图:

可见,作为容器的ViewGroup可以包含作为叶子节点的View,也可以包含作为更低层次的子ViewGroup,而子ViewGroup又可以包含下一层的叶子节点的View和ViewGroup。事实上,这种灵活的View层次结构可以形成非常复杂的UI布局,开发者可据此设计、开发非常精致的UI界面。
一般来说,开发Android应用程序的UI界面都不会直接实用View和ViewGroup,而是使用这两大基类的派生类。
View派生出的直接子类有:AnalogClock,ImageView,KeyboardView, ProgressBar,SurfaceView,TextView,ViewGroup,ViewStub
View派生出的间接子类有:AbsListView,AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView<T extends Adapter>,AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton,
ViewGroup派生出的直接子类有:AbsoluteLayout,AdapterView<T extends Adapter>,FragmentBreadCrumbs,FrameLayout,LinearLayout,RelativeLayout,SlidingDrawer
ViewGroup派生出的间接子类有:AbsListView,AbsSpinner, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, CalendarView, DatePicker, DialerFilter, ExpandableListView, Gallery, GestureOverlayView,GridView,HorizontalScrollView, ImageSwitcher,ListView,
上面View、ViewGroup的直接子类和间接别子类中标记为红色的类是我们再应用开发中接触和用得比较频繁的类,这里特别指出,ImageView是布局具有图片效果的UI常用的类,SurfaceView是用来进行游戏开发的与一般View相比较为特殊的非常重要的类(后续会对原理作深入分析),而AbsoluteLayout、FrameLayout,LinearLayout, RelativeLayout这几个ViewGroup的直接子类是Android UI布局中最基本的布局元素。
值得一提的是,上述的所有基类、派生类都是Android framework层集成的标准系统类,开发者在应用开发中可直接引用SDK中这些系统类及其API。但事实上,在UI开发的很多场景下,直接使用这些系统类并不能满足应用开发的需要。比如说,我们想用ImageView在默认情况下加载一幅图片,但是希望在点击该View时View变换出各种图像处理效果,这个时候直接使用ImageView是不行的,此时我们可以重载ImageView,在新派生出的子控件中重载OnDraw等方法来实现我们的定制效果。这种派生出系统类的子类方法我们通常称之为自定义控件。自定义控件可像标准View控件那样在XML及我们的Java文件中进行布局和实例化,但在布局时必须指出其完整的包名和类名。事实上,自定义控件的使用是我们进行Android 开发的必不可少的基本用法,是必须掌握的基本技巧。
View和ViewGroup最重要的几个方法——
protected void onDraw(Canvas canvas):View类中用于重绘的方法,这个方法是所有View、ViewGroup及其派生类都具有的方法,也是Android UI绘制最重要的方法。开发者可重载该方法,并在重载的方法内部基于参数canvas绘制自己的各种图形、图像效果。
protected void onLayout(boolean changed, int left, int top, int right, int bottom):View类中布局发生改变时会调用的方法,这个方法是所有View、ViewGroup及其派生类都具有的方法,重载该类可以在布局发生改变时作定制处理,这在实现一些特效时非常有用。
protected void dispatchDraw(Canvas canvas):ViewGroup类及其派生类具有的方法,这个方法主要用于控制子View的绘制分发,重载该方法可改变子View的绘制,进而实现一些复杂的视效。
protected boolean drawChild(Canvas canvas, View child, long drawingTime)):ViewGroup类及其派生类具有的方法,这个方法直接控制绘制某局具体的子view,重载该方法可控制具体某个具体子View。
View、ViewGroup是Android UI体系至关重要的两大基类,本文仅对一些最基本的概念、原理和API进行了介绍,大家要全面掌握还需要阅读SDK中对这两个类的介绍并熟悉其API ,并在应用开发中逐渐的加深理解和掌握其用法。
在XML中向ViewGroup中添加组件,这个问题貌似很简单,但是只有在简单中才会发现不简单,其实好多复杂的东西都是由简单的东西一步一步演 化而来的,这是道家所谓的一生二、二生三、三生万物,以后我们还将通过剖析一个布局类来更深入的了解ViewGroup,不过那是后话了,呵呵。
那么我们可以通过怎样的方式来添加了。请看:
<com.fxhy.stady.myviewGroup.HelloViewGroup
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”>
<TextView
android:layout_height=“wrap_content”
android:layout_width=“fill_parent”
android:text=“繁星皓月继承ViewGroup研究”/>
</com.fxhy.stady.myviewGroup.HelloViewGroup>
貌似这个方法可以先ViewGroup中加入组件,但是,实际上我们运行后会发现,其实这个组件是不会显示的。
有兴趣的读者可以运行试试。效果是下面这样的。

二、为啥不显示
那么为啥这个ViewGroup里面的TextView没有显示呢,我也为这个问题困扰过很久,其实,有时候我们不是学不会,而是不会学,知识千万遍,方法有多少。那到底要怎样做呢?
其实很简单,我们只需要在ViewGroup中的onMeasure方法里添加一个对子元素的遍历,并且在onLayout中添加一个布局遍历就实现了简单的布局了。
下面给出代码:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
for(int i = 0; i < childCount; i ++){
View v = getChildAt(i);
v.measure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
for(int i = 0; i < childCount; i ++){
View v = getChildAt(i);
v.layout(l, t, r, b);
}
}
运行效果:

Android原理View、ViewGroup的更多相关文章
- 【Android - 自定义View】之自定义View浅析
1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...
- Android中View和ViewGroup介绍
1. 概念Android中的View与我们以前理解的“视图”不同.在Android中,View比视图具有更广的含义,它包含了用户交互和显示,更像Windows操作系统中的window. ViewGro ...
- java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.L(转)
09-09 10:19:59.979: E/AndroidRuntime(2767): FATAL EXCEPTION: main09-09 10:19:59.979: E/AndroidRuntim ...
- Android的View和ViewGroup分析
1. 概念 Android中的View与我们曾经理解的"视图"不同.在Android中,View比视图具有更广的含义,它包括了用户交互和显示,更像Windows操作系统中的wind ...
- android自定义View&自定义ViewGroup(上)
一般自定义view需要重写的方法 void onMeasure(int widthMeasureSpec, int heightMeasureSpec) void onSizeChanged(int ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android应用层View绘制流程与源码分析
1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...
- Android中View绘制流程以及invalidate()等相关方法分析
[原文]http://blog.csdn.net/qinjuning 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简 ...
- android绘制view的过程
1 android绘制view的过程简单描述 简单描述可以解释为:计算大小(measure),布局坐标计算(layout),绘制到屏幕(draw): 下面看看每一步的动作到底是 ...
随机推荐
- 自制单片机之十七……PC与单片机RS-232串口的通讯和控制
这次我们来试着一步步的去掌握PC与单片机通过RS-232进行通讯和控制. 先说说我硬件的情况.我用的PC是个二手的IBM240小本本,十寸屏,赛扬400,机子很老了.但也有它的优点:1.串口,并口,P ...
- BZOJ2697: 特技飞行
2697: 特技飞行 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 607 Solved: 363[Submit][Status] Descript ...
- URAL 2038 Minimum Vertex Cover
2038. Minimum Vertex Cover Time limit: 1.0 secondMemory limit: 64 MB A vertex cover of a graph is a ...
- 算法导论(第三版)Exercises2.1(插入排序、线性查找、N位大数相加)
关于练习程序的说明参见置顶的那篇. 2.1-1: 31 41 59 26 41 58 31 41 59 26 41 58 31 41 59 26 41 58 26 31 41 59 41 58 26 ...
- POJ 3378
题目链接 查找长度为5的上升序列总数 用的树状数组+高精度 用树状数组求在i前面比i小的数有几个 用的4个树状数组,A[i][j]表示长度为i的以j为结尾的个数,A[i][j]=A[i-1][1... ...
- Android 读取手机SD卡根目录下某个txt文件的文件内容
1.先看activity_main.xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and ...
- Linux中输入命令按tab提示后会自动转义解决方案(xjl456852原创)
linux在命令行输入命令时,如果有$字符,按tab键时会自动在前面加入转义字符,反而达不到自己需要的效果. 例如: 在Centos7下,我要进入一个环境变量,并编辑一个文件: 比如我要进入$JAVA ...
- JavaScript 克隆对象
function clone(origin) { return Object.assign({}, origin); } let aClone = { ...a }; // 等同于 let aClon ...
- leetcode:Minimum Path Sum(路线上元素和的最小值)【面试算法题】
题目: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right w ...
- C#获取文件和文件夹大小
代码如下: /// <summary> /// 获取文件夹大小 /// </summary> /// <param name="dirPath"> ...