View体系

1.View简介

View是Android所有控件的基类,同时ViewGroup也是继承自View。

从上图可以发现我们常用的这些控件都是继承于View。

2.Android坐标系

Android中有两种坐标系,分别为Android坐标系和视图坐标系。

在Android中,将屏幕的左上角的顶点作为Android坐标系的原点,这个原点向右是X轴正方向,原点向下是Y轴正方向。

MotionEvent提供的getRawX()和getRawY()获取的坐标都是Android坐标系的坐标。

3.视图坐标系


试图坐标系

View获取自身宽高

getHeight():获取View自身高度

getWidth():获取View自身宽度

View自身坐标

通过如下方法可以获得View到其父控件(ViewGroup)的距离:

getTop():获取View自身顶边到其父布局顶边的距离

getLeft():获取View自身左边到其父布局左边的距离

getRight():获取View自身右边到其父布局左边的距离

getBottom():获取View自身底边到其父布局顶边的距离

MotionEvent提供的方法

MotionEvent也提供了各种获取焦点坐标的方法:

getX():获取点击事件距离控件左边的距离,即视图坐标

getY():获取点击事件距离控件顶边的距离,即视图坐标

getRawX():获取点击事件距离整个屏幕左边距离,即绝对坐标

getRawY():获取点击事件距离整个屏幕顶边的的距离,即绝对坐标

4.实现View滑动的六种方法

ayout():

view进行绘制的时候会调用onLayout()方法来设置显示的位置,因此我们同样也可以通过修改View的left、top、right、bottom这四种属性来控制View的坐标。

offsetLeftAndRight()与offsetTopAndBottom()

这两种方法和layout()方法效果方法差不多,使用也差不多,我们将ACTION_MOVE中的代码替换成如下代码:


LayoutParams(改变布局参数)

LayoutParams主要保存了一个View的布局参数,因此我们可以通过LayoutParams来改变View的布局的参数从而达到了改变View的位置的效果。

动画

可以采用View动画来移动,在res目录新建anim文件夹并创建translate.xml

scollTo与scollBy

scollTo(x,y)表示移动到一个具体的坐标点,而scollBy(dx,dy)则表示移动的增量为dx、dy。其中scollBy最终也是要调用scollTo的。scollTo、scollBy移动的是View的内容,如果在ViewGroup中使用则是移动他所有的子View。

Scroller

我们用scollTo/scollBy方法来进行滑动时,这个过程是瞬间完成的,所以用户体验不大好。这里我们可以使用Scroller来实现有过度效果的滑动,这个过程不是瞬间完成的,而是在一定的时间间隔完成的。Scroller本身是不能实现View的滑动的,它需要配合View的computeScroll()方法才能弹性滑动的效果。

5.属性动画


1.android视图动画和属性动画

2.android属性动画

ObjectAnimator

ObjectAnimator是属性动画最重要的类,创建一个ObjectAnimator只需通过他的静态工厂类直接返还一个ObjectAnimator对象。参数包括一个对象和对象的属性名字,但这个属性必须有get和set函数,内部会通过java反射机制来调用set函数修改对象的属性值。

ValueAnimator

ValueAnimator不提供任何动画效果,它更像一个数值发生器,用来产生一定规律数字,从而让调用者来控制动画的实现过程。

动画的监听

完整的动画具有start,Repeat,End,Cancel四个过程:

组合动画-AnimatorSet

这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

after(Animator anim) 将现有动画插入到传入的动画之后执行

after(long delay) 将现有动画延迟指定毫秒后执行

before(Animator anim) 将现有动画插入到传入的动画之前执行

with(Animator anim) 将现有动画和传入的动画同时执行

组合动画-PropertyValuesHolder

除了上面AnimatorSet类还可以使用PropertyValuesHolder类来实现组合动画,不过这个组合动画就没有上面的丰富了,使用PropertyValuesHolder类只能多个动画一起执行。当然我们得结合 ObjectAnimator.ofPropertyValuesHolder(Object target,

PropertyValuesHolder… values);方法来使用。

xml中使用属性动画

和视图动画一样,属性动画也可以直接写在xml中:

在res文件中新建animator文件。

6.从源码解析Scroller

1.Scroller的构造函数

要想使用Scroller,必须先调用new Scroller()

2.Scroller的startScroll方法

3.Scroller的computeScrollOffset方法

7.从源码解析View的事件分发机制

1.处理点击事件的方法

View的层级

我们知道View的结构是树形的结构,View可以放在ViewGroup中,这个ViewGroup也可以放到另一个ViewGroup中,这样层层的嵌套就组成了View的层级。

什么是点击事件分发

当我们点击屏幕,就产生了触摸事件,这个事件被封装成了一个类:MotionEvent。而当这个MotionEvent产生后,那么系统就会将这个MotionEvent传递给View的层级,MotionEvent在View的层级传递的过程就是点击事件分发。

点击事件分发的重要方法

点击事件有三个重要的方法它们分别是:

dispatchTouchEvent(MotionEvent ev):用来进行事件的分发

onInterceptTouchEvent(MotionEvent ev):用来进行事件的拦截,在dispatchTouchEvent()中调用,需要注意的是View没有提供该方法

onTouchEvent(MotionEvent ev):用来处理点击事件,在dispatchTouchEvent()方法中进行调用

2.点击事件分发的传递规则

看到这里我们就可以知道点击事件分发的这三个重要方法的关系,用伪代码来简单表示就是:


8.从源码解析Activity的构成

1.从源码解析Activity的构成

2.图解Activity的构成


9.源码解析View的measure流程

1.View的measure流程

先来看看onMeasure()方法(View.java):

看看setMeasuredDimension()方法:

2.ViewGroup的measure流程

ViewGroup的measure原理

讲完了View的measure流程,接下来看看ViewGroup的measure流程,对于ViewGroup,它不只要measure自己本身,还要遍历的调用子元素的measure()方法,ViewGroup中没有定义onMeasure()方法,但他定义了measureChildren()方法(ViewGroup.java)。


LinearLayout的measure流程

ViewGroup并没有提供onMeasure()方法,而是让其子类来各自实现测量的方法,究其原因就是ViewGroup有不同的布局的需要很难统一。


10.从源码解析View的layout和draw流程

1.View的layout流程

2.View的draw流程

11.自定义View

1.自定义View简介

自定义View按照笔者的划分,分为两大类,一种是自定义View,一种是自定义ViewGroup;其中自定义View又分为继承View和继承系统控件两种。这篇文章首先先了解下两大类的其中一种:自定义View。

2.继承系统控件的自定义View

这种自定义View在系统控件的基础上进行拓展,一般是添加新的功能或者修改显示的效果,一般情况下我们在onDraw()方法中进行处理。

3.继承View的自定义View

与上面的继承系统控件的自定义View不同,继承View的自定义View实现起来要稍微复杂一些,不只是要实现onDraw()方法,而且在实现过程中还要考虑到wrap_content属性以及padding属性的设置;为了方便配置自己的自定义View还会对外提供自定义的属性,另外如果要改变触控的逻辑,还要重写onTouchEvent()等触控事件的方法。

你可能感兴趣的:(View体系)