View处理:
绘制(paint canvas path;tween等动画效果)、事件处理
 
参考整理自:
http://a.codekk.com/detail/Android/Trinea/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8B%20View%20%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92
http://a.codekk.com/detail/Android/lightSky/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8B%20View%20%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B

View事件传递
 
 
onTouchListener>onTouchEvent>onTouchEvent.onClickListener
Activity -> Window -> View
 
  • 所有 Touch 事件都被封装成了 MotionEvent 对象,包括 Touch 的位置、时间、历史记录以及第几个手指(多指触摸)等。
  • 事件类型分为 ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以 ACTION_DOWN 开始 ACTION_UP 结束。
  • 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和 OnTouchListener
 
传递流程:
  • (1) 事件从 Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截(return true拦截),从最上层的 View(ViewGroup)开始一直往下(子 View)传递。子 View 可以通过 onTouchEvent()对事件进行处理。
  • (2) 事件由父 View(ViewGroup)传递给子 View,ViewGroup 可以通过 onInterceptTouchEvent()对事件做拦截,停止其往下传递。
  • (3) 如果事件从上往下传递过程中一直没有被停止,且最底层子 View 没有消费事件,事件会反向往上传递,这时父 View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到 Activity 的 onTouchEvent()函数。
  • (4) 如果 View 没有对 ACTION_DOWN 进行消费,之后的其他事件不会传递过来。
  • (5) OnTouchListener 优先于 onTouchEvent()对事件进行消费。
    上面的消费即表示相应函数返回值为 true。
 
 

View绘制流程

View绘制流程:
 
  • measure(int widthMeasureSpec, int heightMeasureSpec):final,measure 调用链最终会回调 View/ViewGroup 对象的 onMeasure()方法,因此自定义视图时,只需要复写 onMeasure() 方法即可。
  • onMeasure(int widthMeasureSpec, int heightMeasureSpec):该方法的参数是父视图对子视图的 width 和 height 的测量要求。在我们自身的自定义视图中,要做的就是根据该 widthMeasureSpec 和 heightMeasureSpec 计算视图的 width 和 height,不同的模式处理方式不同。将计算得到的尺寸,传递给setMeasuredDimension()设置根据 MeasureSpec 计算得到的尺寸

View的测量:MeasureSpec和测量模式
MeasureSpec是一个32位的int值,其中高2位位测量的模式,低30位位测量的大小 (使用位运算是为了提高效率)
测量模式有三种:
(1)EXACTLY:精确值模式,属性设置为精确数值或者match_parent时,系统使用的是EXACTLY模式
(2)AT_MOST:最大值模式,属性设置为wrap_content时,系统使用的是AT_MOST模式
(3)UNSPECIFIED:不指定大小测量模式,通常情况下在绘制自定义View时才会用到

View类默认的onMeasure()方法只支持EXACTLY模式,所以如果在自定义View的时候不重写onMeasure方法的话,就只能使用EXACTLY模式。自定义View可以响应你指定的具体的宽高值或者是match_parent属性,但是,如果要让自定义View支持wrap_content属性的话,那么就必须要重写onMeasure方法来指定wrap_content时view的大小。

重写onMeasure方法的最终工作就是把测量后的宽高值作为参数设置给setMeasuredDimension方法。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//计算width和height
setMeasuredDimension(width, height);
}
  • 在 layout 过程中,子视图会调用getMeasuredWidth()和getMeasuredHeight()方法获取到 measure 过程得到的 mMeasuredWidth 和 mMeasuredHeight,作为自己的 width 和 height。然后调用每一个子视图的layout(l, t, r, b)函数,来确定每个子视图在父视图中的位置。
  • View.draw(Canvas canvas): 由于 ViewGroup 并没有复写此方法,因此,所有的视图最终都是调用 View 的 draw 方法进行绘制的。在自定义的视图中,也不应该复写该方法,而是复写 onDraw(Canvas) 方法进行绘制,如果自定义的视图确实要复写该方法,那么请先调用 super.draw(canvas)完成系统的绘制,然后再进行自定义的绘制。
  • View 的onDraw(Canvas)默认是空实现,自定义绘制过程需要复写的方法,绘制自身的内容在canvas上。
 
  • invalidate():请求重绘 View 树,即 draw 过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些调用了invalidate()方法的 View。
  • requestLayout():当布局变化的时候,比如方向变化,尺寸的变化,会调用该方法,在自定义的视图中,如果某些情况下希望重新测量尺寸大小,应该手动去调用该方法,它会触发measure()和layout()过程,但不会进行 draw。
 
 
 
 
 
 
 

View原理的更多相关文章

  1. 自己定义View Layout过程 - 最易懂的自己定义View原理系列(3)

    前言 自己定义View是Android开发人员必须了解的基础 网上有大量关于自己定义View原理的文章.但存在一些问题:内容不全.思路不清晰.无源代码分析.简单问题复杂化等等 今天,我将全面总结自己定 ...

  2. ios中创建可以拖动的view原理和实现详解

    有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件. 重点是以下一组方法: - (void)touchesBegan:(NSSet *)to ...

  3. 自定义View Draw过程(4)

    目录 目录 1. 知识基础 具体请看我写的另外一篇文章:自定义View基础 - 最易懂的自定义View原理系列 2. draw过程作用 绘制View视图 3. draw过程详解 同measure.la ...

  4. 自定义View Layout过程 (3)

    目录 目录 1. 知识基础 具体请看我写的另外一篇文章:(1)自定义View基础 - 最易懂的自定义View原理系列 2. 作用 计算View视图的位置. 即计算View的四个顶点位置:Left.To ...

  5. 自定义View Measure过程(2)

    目录 目录 1. 作用 测量View的宽/高 在某些情况下,需要多次测量(measure)才能确定View最终的宽/高: 在这种情况下measure过程后得到的宽/高可能是不准确的: 建议在layou ...

  6. 自定义View基础 (1)

    前言 自定义View原理是Android开发者必须了解的基础: 在了解自定义View之前,你需要有一定的知识储备: 本文将全面解析关于自定义View中的所有知识基础. 目录 目录 1. View的分类 ...

  7. Android自己定义View基础篇(三)之SwitchButton开关

    自己定义View基础篇(二) 自己定义View基础篇(一) 自己定义View原理 我在解说之前,先来看看效果图,有图有真相:(转换gif图片效果太差) 那来看看真实图片: 假设你要更改样式,请改动例如 ...

  8. Path类的最全面具体解释 - 自己定义View应用系列

    前言 自己定义View是Android开发人员必须了解的基础:而Path类的使用在自己定义View绘制中发挥着很关键的数据 网上有大量关于自己定义View中Path类的文章.但存在一些问题:内容不全. ...

  9. 进阶之路 | 奇妙的View之旅

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习清单: View是什么 View的位置参数 View的触控 View的滑动 涉及以下各个知识点: View ...

随机推荐

  1. ubuntu远程连接

     apt-cache search openssh-server   //直接用apt-get install openssh-server安装.记不清包名字时可用apt-cache search o ...

  2. hibernate_validator_02

    三种不通的注解 1. 字段级(field level) 约束 package com.mycompany; import javax.validation.constraints.NotNull; p ...

  3. cocos2d-x 实现沙子特效

    效果图. 说明. 标题取的不好, 原因是我也不知道这效果应该叫什么. 大概效果是这样的, 随着鼠标按下并且移动, 所到之处所有磁铁都将扩散. 就好比鼠标是一个圆形区域去排挤在场的磁铁. 话不多说, 直 ...

  4. CRM窗体中只读的控件不会引发Update事件

    在CRM的窗体设计时,如果把某一个控件设为只读了,仅管你在后台用代码修改了值,这个值也不会起任何作用,更不会提交到后台,触发Update事件!

  5. Smarty 模板引擎 fetch()和display()函数的区别?

    Smarty模板函数里面有这样一个方法:fetch("template.htm"),他和display("template.htm");最大的不同就是fetch ...

  6. Dede 列表文章 自增

    在{dede:arclist/}这个标签中有个[field:global.autoindex/],是从0开始自增,如果我们想自定义一个数值,比如自定义从2开始.那么就可以写成下面代码: [field: ...

  7. jdom学习:读取xml文件

    用JDOM读取XML文件需先用org.jdom.input.SAXBuilder对象的build()方法创建Document对象,然后用Document类.Element类等的方法读取所需的内容.IB ...

  8. linux c信息验证程序(分享)

    程序来源是Hirst First c,程序很简单,但却是很好的说明了一个检测信息是否被串改的原理.下载程序的时候是否都有看到提供md5效验值的呢,原理其实和这个小程序相似:就是对程序的内容进行某种计算 ...

  9. asp.net webform 局部发布更新

    一:关于webform编译 编译时会将每个aspx文件单独生成dll文件于bin目录下.也会将引用的dll存放于bin目录 二:对界面或者引用的dll(如BLL层,DAL层等)做了修改更新后在服务器只 ...

  10. SPSS相关和回归分析

    1.语文和数学成绩都受IQ的影响而且相互影响,则分析语文和数学的关系时需要偏相关分析.2.距离分析用于探索相似性,比如给了某年的12个月三个城市的气温数据,然后分析,会得到一个相似性矩阵,这是个对称阵 ...