温故而知新,系统整理一下。

1. View是什么?

1). View类是所有用来构建用户界面的组件的基类
2). ViewGroup是View的一个子类, 是各种布局的基类,它是包含其它View或ViewGroup和定义这些孩子布局参数的容器
3). 一个View(ViewGroup)占用屏幕上的一个矩形区域, 它负责界面的绘制和事件处理
4). 手机屏幕上所有看得见摸得着的都是View(包括ViewGroup)

2. View的分类

1).  不能包含子View的View: 一般的View
      TextView Button ImageView  EditText/RadioButton/Checkbox
2). 可以包含子View的View: ViewGroup
      FrameLayout  RelativeLayout LinearLayout ScrollView ListView GridView

3. ViewGroup

1). ViewGroup extends View implements ViewParent, ViewManager
2). ViewManager: 用来添加、删除、更新布局
     addView(View v)
     removeView(View v)
     updateViewLayout(View v)
3). ViewParent: 提供了一系列操作子View的方法

4. 关于View和ViewGroup

1). 整个界面只会有一个根View
     a. 得到它: window.getDecorview()      PhoneWindow$decorView
     b. 本质类型: FrameLayout
     c. setContentView()添加的视图不是整个界面的根view       FrameLayout(id=content)  
2). 一个View只会有一个父View(ViewGroup), 一个ViewGroup可以有多个子View
     a. 得到父视图: view.getParent(), 可以将返回的ViewParent强转为指定的ViewGroup
     b. 不是所有的View都能添加子view, 只有ViewGroup及其子类才能添加

5. 区别View与Activity?

1). Activity是四大组件中唯一能与用户进行直接交互的组件
2). Activity只是控制和管理View, 真正显示和处理事件的是View本身来完成
3). Activity内部有一个window对象, window对象(Phonewindow)中包含一个FramLayout类型的decorView
     在Activity中setContentView(view)实质上是将view添加到decorView中
     手机屏幕中显示的根布局就是decorView

6. 显示ContentView的3种方式:

1). setContentView(R.layout.activity_main);
2). View view = View.inflate(this, R.layout.activity_main, null);
     setContentView(view);
3). MyTextView tv = new MyTextView(this);
     setContentView(tv);

7. View的生命周期过程:

1). 创建View对象
     a. 存在2种创建的方式: 加载布局文件创建和直接new构造方法创建
     b. 布局文件方式的本质: 解析布局xml, 根据标签名创建对应的View对象, 并将标签属性设置到对象中(构造方法)
     c. 布局文件方式: 在所有的View对象都创建好了后, 会调用onFinishInflate()
     d. 在视图对象都创建好后, 调用onAttachedToWindow(), 表明view对象关联到window上了
2). 测量(多大?)
     a.方法执行: measure()--->onMeasure()--->setMeasuredDimension()
     b. measure(): 用来确定当前View的大小, 它是final的方法不能重写, 它内部调用了onMeasure()
     c.onMeasure(): 一般重写此方法, 根据我们的实际需求, 对View进行测量, 并保存宽高
     d. setMeasuredDimension(): onMeasure()中必须调用些方法保存当前View测试出的宽度和高度
3). 布局(在哪?)
     a. 方法执行: layout()--->onLayout()
     b. layout(l, t, r, b): 
          ①. 指定View的左上角点的坐标和右下角点的坐标
          ②. 比较原有的l,t,r,b与当前的l,t,r,b, 如果有变化了或请求重新layout, 就会调用onLayout(l,t,r,b)
          ③. 不会重写些方法, 只会调用些方法来指定当前View在父View中的位置
     c. onLayout(changed, l, t, r, b)
          ①. 决定当前view在父ViewGroup中的位置
          ②. 在View类中只是空实现, View还不知道在此方法中做什么工作, 需要子View来去重写此方法实现所需要的
          ③. 在ViewGroup类中用来指定子View的位置, 但是abstract
                    FrameLayout
                    LinearLayout
                    RelativeLayout
          ④. LinearLayout的实现:
     判断自身是横屏还是竖屏?               遍历所有的子View, 为它们准备l,t,r,b               如果是垂直:                    A (0,0,width1,height1),                    B (0,height1,width2,height1+height2),                    C (0,height1+height2,width3,height1+height2+height3)               如果是水平:                    (0,0,width1,height1),                    (height1,0,height1+width2,height2),                    (height1+height2,0,height1+height2+width3,height3)   
     d. 可以通过requestLayout()的方式来强制重新layout
4). 绘制(啥样?)
     a. 方法执行: draw()--->onDraw()
     b. draw(): 
          ①. 画一些通用的东西(如背景,滚动条等), 一般不会去重写此方法
               1>. Draw the background(画背景)
               2>. Draw view's content(画内容)
               3>. Draw children(画子View)
               4>. Draw decorations scrollbars (画滚动条)
          ②. 如果是View, 使用onDraw(canvas)来画界面
          ③. 如果是ViewGroup, 使用dispatchDraw(canvas)---分发给子View绘制
     c. onDraw(Canvas canvas)
          ①. 所有特定的View(比如:TextView/ImageView)都重写了此方法来绘制自己的样子
          ②. 主要使用Paint和Canvas来绘制
     d. 可以通过调用inValidate()或postInValidate()来强制重绘
5). 事件处理: 
     a. 相关方法: 
          onTouchEvent(MotionEvent): 触摸事件的回调方法
          OnTouchListener--->onTouch(View v, MotionEvent event) : 触摸事件的监听器
     b. 事件的分发和处理过程
6). 死亡:
     b. 相关方法: onDetachedFromWindow()
     c. 当Activity退出或当前View被移除触发

8. 总结:

creation
     二种方式 : new 构造方法(context) ,  定义布局文件再加载(setContentView()/View.inflate()---(context, AttributeSet))      
     全类名<TextView>               <com.atguigu.MyTextView>
     所有View对象都创建好了--->onFinishInflate()[必须是布局文件]--->onAttachToWindow()  --->getViewAt(int position)
measure(多大?)
     -->measure()--->onMearsure()    产生一个测量的尺寸(宽高)  --->getMearsureHeight()  getMearsureWidth()     -->onResume()
layout(在哪?)
     --->layout(l, t, r, b)--->onLayout(boolean change, l, t, r, b)
     requestLayout(): 强制重新布局
draw(撒样?)
     draw()--->onDraw()       
     invalidate()/postInvalidate(): 强制重绘
event deal
     onTouchEvent()
          return true;  消费事件     --->拦截事件
die
     onDetachedFromWindow()

——相关资料推荐
自定义View,有这一篇就够了

Android自定义控件,你们是如何系统学习的
Android中View绘制流程以及invalidate()等相关方法分析
Android 自定义控件实现刮刮卡效果 真的就只是刮刮卡么
Android自定义软键盘的实现