自定义view知识储备

来源:互联网 发布:淘宝如何自创服装品牌 编辑:程序博客网 时间:2024/05/18 13:24

自定义View的三个构造函数

 public DIY_View(Context context){ //创建对象的时候调用        super(context);    } public DIY_View(Context context,AttributeSet attrs){ //加载布局文件的时候调用 将布局文件转换成一个view对象        super(context, attrs);    }public DIY_View(Context context,AttributeSet attrs,int defStyleAttr ){//加载自定义属性的时候调用        super(context, attrs,defStyleAttr);

View视图的结构

这里写图片描述

无论是onMeasure()过程 onLayout()过程还是onDraw (),都是从view的根节点开始测量或者计算,一个分支一个分支的进行,即树形递归;

1.View的坐标描述(view的位置是相对于父控件而言)

  • Top:子View上边界到父view上边界的距离;
  • Left:子View左边界到父view左边界的距离;
  • 子View下边距到父View上边界的距离 ;
  • Right:子View右边界到父view左边界的距离;

2.位置的获取方式

  • view的位置获取是通过view.getxxx()
 getLeft();      //获取子View左上角距父View左侧的距离 getBottom();    //获取子View右下角距父View顶部的距离
  • get()与getRaw的区别
    get() :触摸点相对于其所在组件坐标系的坐标
    getRaw():触摸点相对于屏幕的默认坐标系的坐标的位置

绘制流程

onMeasure(测量)、onLayout(遍历布局)、onDraw (绘制)

测量流程–onMeasure

  • ViewGroup.LayoutParams (View 自身的布局参数)
  • MeasureSpecs 类(父视图对子视图的测量要求)
    ViewGroup.LayoutParams
    用来指定视图的高度和宽度
    fill_parent 子view填充父容器
    match_parent 子view填充父容器
    wrap_content 自适应大小,强制性地使视图扩展以便显示其全部内容(含 padding )

MeasureSpec
封装了父容器对 view 的布局上的限制,内部提供了宽高的信息( SpecMode 、 SpecSize ),SpecSize是指在某种SpecMode下的参考尺寸,其中SpecMode 有如下三种:

  1. UNSPECIFIED
    父控件不对子view有任何的限制,一般适用于系统的内部,表示测量状态,一般view用不到 listview ;
  2. EXACTLY
    父控件指定子view精确的大小 填充;
  3. AT_MOST
    子view的大小不能大于父控件给你指定的大小,具体的大小由自己来定,包裹内容。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }

对于getSuggestedMinimumWidth和getSuggestedMinimumHeight方法,顾名思义,就是得到建议的最小的宽/高。
总结:view的测量是由父控件的测量规格和自身的LayoutParams决定的。

View 的 layout 过程

ViewGroup 用来确定子元素的位置。在onlayout遍历所有的child并调用其layout。
方法
在父容器的 onLayout 中通过 child.layout 来放置 view 到任意位置
在自己的 onLayout 中修改 mLeft/mRight/mTop/mBottom

View 的 draw 过程

大致流程

  1. 画背景 background.draw(canvas)
  2. 绘制自己( onDraw )
  3. 绘制 children ( dispatchDraw )
  4. 绘制装饰( onDrawScrollBars )
    备注:
    dispatchDraw 会遍历调用所有 child 的 draw ,如此 draw 事件就一层层地传递了下去。

view的滑动冲突

考虑水平、和竖直方向的滑动距离、速度、以及角度来判断到底谁来拦截事件;
通用方法:重写父控件的OnInterceptTouchEvent函数,在move的时候返回true,比如左右滑动的时候返回true,其他返回false,这样左右移动父控件就能处理,其他上下移动事件交给子view来处理;

#