View体系

View视图坐标与方法

简介

Android View体系是界面编程的核心。
View是Android所有控件的基类,同时ViewGroup也是继承自View。
View体系

坐标系

Android坐标系

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

视图坐标系

getHeight():获取View自身高度
getWidth():获取View自身宽度
View体系
获得View到其父控件(ViewGroup)的距离:

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

最终的点击事件都会由onTouchEvent(MotionEvent event)方法来处理

getX():获取点击事件距离控件左边的距离,即视图坐标
getY():获取点击事件距离控件顶边的距离,即视图坐标
getRawX():获取点击事件距离整个屏幕左边距离,即绝对坐标
getRawY():获取点击事件距离整个屏幕顶边的的距离,即绝对坐标

滑动

简介

View的滑动是Android实现自定义控件的基础。
当触摸事件传到View时,系统记下触摸点的坐标,手指移动时系统记下移动后的触摸的坐标并算出偏移量,并通过偏移量来修改View的坐标。

六种滑动的方法

1.layout()

View进行绘制的时候会调用onLayout()方法来设置显示的位置,因此我们同样也可以通过修改View的left、top、right、bottom这四种属性来控制View的坐标。计算偏移量,再调用layout()方法重新放置这个自定义View的位置。
每次移动时都会调用layout()方法来对自己重新布局,从而达到移动View的效果。

2.offsetLeftAndRight()与offsetTopAndBottom()

和layout()方法效果方法差不多,使用也差不多
对left和right进行偏移
offsetLeftAndRight();
对top和bottom进行偏移
offsetTopAndBottom();

3.LayoutParams(改变布局参数)

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

4.View动画
属性动画(重要)

Android视图动画和属性动画
相比属性动画视图动画非常大的缺陷是不具有交互性,当某个元素发生视图动画后,其响应 事件的位置依然在动画前的地方,所以视图动画只能做普通的动画效果,避免交互的发生。但 是它的优点也非常明显:效率比较高使用也方便。

Android属性动画
在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进 行更精细化的控制,控制一个对象和一个属性值,而使用多个ObjectAnimator组合到AnimatorSet形成一个动画。属性动画通过调用属性get,set方法来真实地控制了一个View的属性值,因此强大的属性动画框架,基本可以实现所有的动画效果。

5.scollTo与scollBy

scollTo(x,y)表示移动到一个具体的坐标点,而scollBy(dx,dy)则表示移动的增量为dx、dy。其中scollBy最终也是要调用scollTo的。scollTo、scollBy移动的是View的内容,如果在ViewGroup中使用则是移动他所有的子View。
这里要实现CustomView随着我们手指移动的效果的话,我们就需要将偏移量设置为负值。

6.Scroller

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

View的工作流程

首先有必要了解Activity构成

一个Activity包含一个window对象,这个对象是由PhoneWindow来实现的,PhoneWindow将DecorView做为整个应用窗口的根View,而这个DecorView又将屏幕划分为两个区域一个是TitleView一个是ContentView,而我们平常做应用所写的布局正是展示在ContentView中的。

图解Activity构成

View体系

1.measure

用来测量View的宽高

measure流程分为View的measure流程、ViewGroup的measure流程和LinerLayout的measure流程,只不过ViewGroup的measure流程除了要完成自己的测量还要遍历去调用子元素的measure()方法。

2.layout

用来确定View的位置

3.draw

用来绘制View

draw流程有六个步骤
1.如果有设置背景,则绘制背景
2.保存canvas层(可跳过)
3.绘制自身内容
4.如果有子元素则绘制子元素
5.绘制效果(可跳过)
6.绘制装饰品(scrollbars)

自定义View

自定义View借助原著笔者的划分,分为两大类,一种是自定义View,一种是自定义ViewGroup;

1.自定义View

自定义View分为继承View和继承系统控件两种。

- 继承系统控件的自定义View

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

- 继承View的自定义View

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

自定义属性

android系统的控件以android开头的比如android:layout_width,这些都是系统自带的属性,为了方便配置RectView的属性,我们也可以自定义属性。

自定义控件

自定义组合控件就是多个控件组合起来成为一个新的控件,主要用来解决多次重复的使用同一类型的布局。比如我们应用的顶部的标题栏,还有弹出的固定样式的dialog,这些都是常用的,所以把他们所需要的控件组合起来重新定义成一个新的控件。

2.自定义ViewGroup

一个自定义的ViewGroup,左右滑动切换不同的页面,类似一个特别简化的ViewPager。

自定义步骤:
1.继承ViewGroup
2.对wrap_content属性进行处理
3.实现onLayout
4.处理滑动冲突
5.弹性滑动到其他页面
6.快速滑动到其他页面
7.再次触摸屏幕阻止页面继续滑动
8.应用HorizontalView