Android系统知识全览---View知识体系(2)---Vi

2018-08-19  本文已影响22人  善笃有余劫

View的事件体系

View的概念

View是界面上控件的在代码层的抽象体现。所有控件继承于View基类,根据功能可以分为View和ViewGroup。其中ViewGroup表示控件组,可以放置控件View。

View的属性参数

View的位置属性:

left、right、top、bottom、elevation

image

如图所示:

同理可以得出View.width=right-left,View.height=bottom-top

translationX、translationY、translationZ

这三个参数代表的是在动画或者滑动View的时候,View的当前位置相对于其原始位置平移的距离:

translation 翻译; 译本; 转化; 转变;

x、y、z

这三个参数代表的是View的当前位置相对于其父控件的距离:

x = left + translationX;
y = top + translationY;
z = elevation + translationZ;

值得注意的是 View在平移动作,参考点是左上角 所以 所谓的移动距离也只能是相对于左上角坐标的变化。

View的事件

MotionEvent和TouchSlop

View可以接受和处理类似点击 长按 双击等动作。这里有个MotionEvent可以接受处理。

因此,对于我们常常做的一些操作,相应的事件触发顺序如下:

使用MotionEvent类,我们还可以获取到触摸屏幕时View的一些位置参数:

TouchSlop指的是 认为是滑动的最小距离。也就是在屏幕上滑动距离大于等于这个数才能算是滑动。

通过如下方式即可获取这个常量

ViewConfiguration.get(getContext()).getScaledTouchSlop();

View事件的工具类VelocityTracker/GestureDetector/Scroller

VelocityTracker

VelocityTracker用于追踪手指滑动的速度。具体使用过程如下:

public class TestVelocityView extends View {

    //用于回调的接口
    GetVelocityListener listener;
    //追踪速度关键的类。没有这个这篇文章将毫无意义
    VelocityTracker velocityTracker;
    //要画文字或者任何东西都需要的paint
    Paint paint = new Paint();

    public GetVelocityListener getListener() {
        return listener;
    }

    public void setListener(GetVelocityListener listener) {
        this.listener = listener;
    }

    public TestVelocityView(Context context) {
        this(context,null);
    }

    public TestVelocityView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public TestVelocityView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint.setTextSize(50);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //画文字的代码。
        canvas.save();
        paint.setColor(Color.BLACK);
        canvas.drawText("x = "+xVelocity+"y ="+yVelocity,getLeft(),getTop(),paint);
      //画完之后回收一下
        canvas.restore();
    }

    int xVelocity = 0;
    int yVelocity = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //初始化
                velocityTracker = VelocityTracker.obtain();
                break;
            case MotionEvent.ACTION_MOVE:
              //追踪
                velocityTracker.addMovement(event);
                velocityTracker.computeCurrentVelocity(1000);
                xVelocity = (int) velocityTracker.getXVelocity();
                yVelocity = (int) velocityTracker.getYVelocity();

                if (listener != null) {
                    listener.get(xVelocity, yVelocity);
                    //强制刷新一下view,否则不会一直掉onDraw。
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                //回收
                velocityTracker.clear();
                velocityTracker.recycle();
                break;
        }
        return true;
    }

    public interface GetVelocityListener {
        public void get(int x, int y);
    }
}
  1. 实例化VelocityTracker对象 velocityTracker = VelocityTracker.obtain();
  2. TouchEvent方法中给VelocityTracker对象绑定MotionEvent对象
  3. 使用computeCurrentVelocity设置速度的时间单位(会影响到后面获取的结果)比如设置为100ms v=100/100ms,如果设置为1000ms,得出的结果为v=1000/1000ms。
  4. 获取 横向 纵向 速度xVelocity = (int) velocityTracker.getXVelocity();
    yVelocity = (int) velocityTracker.getYVelocity();

最后记得回收:

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

GestureDetector

手势检测的工具类,用于检测用户的单击 双击 滑动 长按等事件。

具体使用如下:
0.继承GestureDetector.OnGestureListener接口
于此同时还有6个方法:

@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 event1, MotionEvent event2, float velocityX, float velocityY) {
        
        return false;
    }

1.定义手势检测器实例,使用``GestureDetector.OnGestureListener`实例化对象。

GestureDetector detector=new GestureDetector(this);
//解决长按无法移动屏幕问题
 detector.setIsLongpressEnabled(false);

2.View的onTouchEvent中 直接交给

@Override
    public boolean onTouchEvent(MotionEvent me) {
        //将该Activity上的触碰事件交给GesturDetector处理
        return detector.onTouchEvent(me);
    }

3.除了以上的6个事件,还有一些而外的事件需要单独添加接口OnDoubleTapListener

detector.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;
            }
        });

1.onSingleTapConfirmed 严格的单击事件
2.onDoubleTap 双击事件 不和 onSingleTapConfirmed 一起
3.onDoubleTapEvent 发生了双击事件

Scroller

弹性滑动辅助类,能帮助View实现一个带过度的滑动。

使用如下:

View的滑动

使用上节介绍的Scroller即可,当然也可以用其他方式

普通的滑动()

1.scrollTo、scrollBy 只能滑动View的内容 生硬

  1. 使用动画位移 但是View动画只能滑动UI,不能真正滑动View。使用属性动画可以,通过动画改变translationX 和translationY
    3.改变View的布局参数 设置LayoutParams的Margin参数即可

使用Scroller能弹性的滑动过去。

上一篇下一篇

猜你喜欢

热点阅读