Android 从0开始自定义控件之 View 基础知识与概念(一)

来源:互联网 发布:支付宝自动发货源码 编辑:程序博客网 时间:2024/06/06 05:32

转载请标明出处: http://blog.csdn.net/airsaid/article/details/53057091
本文出自:周游的博客

  • 前言
  • 什么是View
  • View位置参数
  • MotionEvent
  • TouchSlop
  • VelocityTracker
  • GestureDetector
  • 参考

前言

自定义 View 可以说是 Android 路上的一道坎,会的人觉得简单,不会的觉得很难。最近正好在看《Android开发艺术探索》讲的自定义 View 这里,于是打算从头理一理自定义 View,写写笔记,方便日后自己查阅也希望能帮助到你。

什么是View

View作为用户界面组件的基本构建块,在屏幕上占据一个矩形区域,负责绘图和事件的处理。View是Android中所有控件的基类,像TextView、Button、LinearLayout都是间接或直接继承自View。除了View之外,还有一个比较重要的控件:ViewGroup。ViewGroup也是继承自View,和View不同的是,View主要用于创建交互式UI组件,而ViewGroup则表示一个控件组,布局Layout都继承自该类,其内部可以包含多个控件。

View位置参数

View最重要的莫过于View的位置参数了,View的位置,主要用4个点组成,分别对应View的四个属性:left、rigth、top、buttom。其中left是左上角横坐标,top是左上角纵坐标,right是右上角横坐标,buttom是右下角纵坐标。如下图:
这里写图片描述

注意事项
这些坐标都是根据当前View的父容器来决定的,而并不是根据当前屏幕。

从Android3.0开始,View增加了几个额外的属性:x、y、translationX、translationY。其中x、y是View左上角的坐标,而translationX、和translationY则是View左上角相对于父容器的偏移量。这几个参数也都是相当于父容器的,并且translationX、translationY的默认值为0。其换算公式如下:

x = left + translationXy = top + translationY

MotionEvent

通过MotinoEvent对象我们可以获取的用户触摸到手机屏幕产生的事件,通常的触摸事件有如下几种:

  • ACTION_DOWM:手指刚接触屏幕。
  • ACTION_MOVE:手指在屏幕上移动。
  • ACTION_UP:手指在屏幕上松开的一瞬间。

同时我们还可以同时获取到,用户触摸时的x、y坐标。我们可以通过getX()、getY()、getRawX()、getRawY()来获取。其中getX()、getY()是获取的相对于当前View左上角的x、y坐标。而getRawX()、getRawY()则获取的是相对于手机屏幕左上角的x、y坐标。

TouchSlop

TouchSlop是一个常量,保存的是系统所能识别出的最小滑动距离。这个值在不同的设备上有可能是不同的,我们通常使用它来进行一些滑动过滤,比如说判断当前滑动的距离如果少于这个值,那么就可以判断不是滑动,不进行滑动后的处理,增强用户体验。

我们可以通过:

ViewConfiguration.get(this).getScaledTouchSlop();

来获取TouchSlop这个值。

VelocityTracker

VelocityTracker,速度追踪,通过这个类我们可以获取手指在滑动时的速度,其中包括水平和垂直方向的速度。
获取第一步,在View的onTouch()方法中添加追踪:

VelocityTracker velocityTracker = VelocityTracker.obtain();velocityTracker.addMovement(event);

第二步,获取当前滑动速度:

velocityTracker.computeCurrentVelocity(1000);float xVelocity = velocityTracker.getXVelocity();float yVelocity = velocityTracker.getYVelocity();

需要注意的是,在获取之前,必须先要调用computeCurrentVelocity(int units)方法,其中units参数代表的是毫秒时间段。比如说上方写的1000就代表1秒内手指滑动的像素数,如果1秒内滑动了100像素数,那么值就为100,当然这个值也有可能是负数,如果是在水平方向从右往左滑动,值则会负数,垂直时,从下往上滑动,也为负数。总结下来可以用一个公式来表示:

速度 = (终点位置 - 起点位置) / 时间段
当我们不需要使用VelocityTracker的时候,可以通过如下方法重置并回收内存:

velocityTracker.clear();velocityTracker.recycle();

GestureDetector

GestureDetector是一个手势检测类,用于辅助我们检测用户的手势动作,比如说:单击、双击、长按、滑动等行为。
GestureDetector的使用也很简单,主要分如下几步:

  • 第一步(创建对象):
GestureDetector gestureDetector = new GestureDetector(new GestureDetector.OnGestureListener() {    @Override    public boolean onDown(MotionEvent e) {        return false;    }    @Override    public void onShowPress(MotionEvent e) {    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        return false;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        return false;    }    @Override    public void onLongPress(MotionEvent e) {    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        return false;    }});

其中,构建对象的参数为一个监听接口。如果只需要单独监听某个事件,可以实现如下监听:

GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener(){    // 实现需要实现的方法});
  • 第二步(重写onTouchEvent()方法,接管触摸事件):
@Overridepublic boolean onTouchEvent(MotionEvent event) {    boolean consume = mGestureDetector.onTouchEvent(event);    return consume;}

至此,我们我们就可以获取到用户触摸时的状态了,当用户触摸时分别会调用对应回调方法。具体的方法描述如下:

方法名 描述 onDown 手指轻轻触摸屏幕的一瞬间触发 onShowPress 手指轻轻触摸屏幕,尚未松开或拖动时触发 onSingleTapUp 手指轻轻触摸屏幕后松开时触发 onScroll 手指按下屏幕后拖动时触发 onLongPress 长按屏幕时触发 onFling 按下屏幕,快速滑动后松开时触发

我们不仅可以获取到用户的如上触摸状态,还可以通过GestureDetector的setOnDoubleTapListener(listener)方法获取用户的双击等事件:

mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {    @Override    public boolean onSingleTapConfirmed(MotionEvent e) {        return false;    }    @Override    public boolean onDoubleTap(MotionEvent e) {        return false;    }    @Override    public boolean onDoubleTapEvent(MotionEvent e) {        return false;    }});

其中各回调方法说明如下:

方法名 描述 onSingleTapConfirmed 严格的单击行为(只允许出现一次单击行为,如果触发了该事件,那么后面不可能再有单击事件。即只可能是单击,而不是双击中的一次。) onDoubleTap 双击时触发(该方法不可与onSingleTapConfirmed()方法共存) onDoubleTapEvent 表示发生了双击行为,在双击的期间,ACTION_DOWN、ACTION_MOVE和ACTION_UP都会触发该回调

参考

《Android开发艺术探索》

下篇:Android 从0开始自定义控件之View的滑动(二)

3 0