Android基础之View和ViewGroup的区别

写代码的四点:

     1.明确需求。要做什么?

     2.分析思路。要怎么做?(1,2,3……)

     3.确定步骤。每一个思路要用到哪些语句、方法和对象。

     4.代码实现。用具体的语言代码将思路实现出来。

 

学习新技术的四点:

     1.该技术是什么?

     2.该技术有什么特点?(使用需注意的方面)

     3.该技术怎么使用?(写Demo)

     4.该技术什么时候用?(在Project中的使用场景 )

----------------------早计划,早准备,早完成。-------------------------

        Android的UI界面都是由View和ViewGroup及其派生类组合而成的。其中,View是所有UI组件的基类,而ViewGroup是容纳View及其派生类的容器,ViewGroup也是从View派生出来的。一般来说,开发UI界面都不会直接使用View和ViewGroup(自定义控件的时候使用),而是使用其派生类。

        下图:UI布局的层次结构。

 

 

View和ViewGroup的区别:

        可以从两方面来说:

        一.事件分发方面的区别;

        二.UI绘制方面的区别;

 

事件分发方面的区别:

        事件分发机制主要有三个方法:dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()

        1.ViewGroup包含这三个方法,而View则只包含dispatchTouchEvent()、onTouchEvent()两个方法,不包含onInterceptTouchEvent()。

        2.触摸事件由Action_Down、Action_Move、Action_Up组成,一次完整的触摸事件,包含一个Down和Up,以及若干个Move(可以为0);

        3.在Action_Down的情况下,事件会先传递到最顶层的ViewGroup,调用ViewGroup的dispatchTouchEvent(),①如果ViewGroup的onInterceptTouchEvent()返回false不拦截该事件,则会分发给子View,调用子View的dispatchTouchEvent(),如果子View的dispatchTouchEvent()返回true,则调用View的onTouchEvent()消费事件。②如果ViewGroup的onInterceptTouchEvent()返回true拦截该事件,则调用ViewGroup的onTouchEvent()消费事件,接下来的Move和Up事件将由该ViewGroup直接进行处理。

        4.当某个子View的dispatchTouchEvent()返回true时,会中止Down事件的分发,同时在ViewGroup中记录该子View。接下来的Move和Up事件将由该子View直接进行处理。

        5.当ViewGroup中所有子View都不捕获Down事件时,将触发ViewGroup自身的onTouch();触发的方式是调用super.dispatchTouchEvent函数,即父类View的dispatchTouchEvent方法。在所有子View都不处理的情况下,触发Acitivity的onTouchEvent方法。

        6..由于子View是保存在ViewGroup中的,多层ViewGroup的节点结构时,上层ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象。如ViewGroup0——ViewGroup1——TextView的结构中,TextView返回了true,它将被保存在ViewGroup1中,而ViewGroup1也会返回true,将被保存在ViewGroup0中;当Move和Up事件来时,会先从ViewGroup0传递到ViewGroup1,再由ViewGroup1传递到TextView,最后事件由TextView消费掉。

        7.子View可以调getParent().requestDisallowInterceptTouchEvent(),请求父ViewGroup不拦截事件。

 

UI绘制方面的区别:

        UI绘制主要有五个方法:onDraw(),onLayout(),onMeasure(),dispatchDraw(),drawChild()

        1.ViewGroup包含这五个方法,而View只包含onDraw(),onLayout(),onMeasure()三个方法,不包含dispatchDraw(),drawChild()。

        2.绘制流程:onMeasure(测量)——》onLayout(布局)——》onDraw(绘制)。

        3.绘制按照视图树的顺序执行,视图绘制时会先绘制子控件。如果视图的背景可见,视图会在调用onDraw()之前调用drawBackGround()绘制背景。强制重绘,可以使用invalidate();

        4.如果发生视图的尺寸变化,则该视图会调用requestLayou(),向父控件请求再次布局。如果发生视图的外观变化,则该视图会调用invalidate(),强制重绘。如果requestLayout()或invalidate()有一个被调用,框架会对视图树进行相关的测量、布局和绘制。

        注意:视图树是单线程操作,直接调用其它视图的方法必须要在UI线程里。跨线程的操作必须使用Handler。

        5.onLayout():对于View来说,onLayout()只是一个空实现;而对于ViewGroup来说,onLayout()使用了关键字abstract的修饰,要求其子类必须重载该方法,目的就是安排其children在父视图的具体位置。

        6.draw过程:drawBackground()绘制背景——》onDraw()对View的内容进行绘制——》dispatchDraw()对当前View的所有子View进行绘制——》onDrawScrollBars()对View的滚动条进行绘制。

 

 

方法说明:

        1.onDraw(Canvas canvas):UI绘制最重要的方法,用于UI重绘。这个方法是所有View、ViewGroup及其派生类都具有的方法。自定义控件时,可以重载该方法,并在内容基于canvas绘制自定义的图形、图像效果。

        2.onLayout(boolean changed, int left, int top, int right, int bottom):布局发生变化时调用此方法。这个方法是所有View、ViewGroup及其派生类都具有的方法。自定义控件时,可以重载该方法,在布局发生改变时实现特效等定制处理。

        3.onMeasure(int widthMeasureSpec, int heightMeasureSpec):用于计算自己及所有子对象的大小。这个方法是所有View、ViewGroup及其派生类都具有的方法。自定义控件时,可以重载该方法,重新计算所有对象的大小。 MeasureSpec包含了测量的模式和测量的大小,通过MeasureSpec.getMode()获取测量模式,通过MeasureSpec.getSize()获取测量大小。mode共有三种情况: 分别为MeasureSpec.UNSPECIFIED( View想多大就多大), MeasureSpec.EXACTLY(默认模式,精确值模式:将layout_width或layout_height属性指定为具体数值或者match_parent。), MeasureSpec.AT_MOST( 最大值模式:将layout_width或layout_height指定为wrap_content。)。

        4.dispatchDraw(Canvas canvas):ViewGroup及其派生类具有的方法,主要用于控制子View的绘制分发。自定义控件时,重载该方法可以改变子View的绘制,进而实现一些复杂的视效。

        5.drawChild(Canvas canvas, View child, long drawingTime):ViewGroup及其派生类具有的方法,用于直接绘制具体的子View。自定义控件时,重载该方法可以直接绘制具体的子View。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值