View的基础知识

下面主要说一些 View 的基础知识,从而为后面更好的理解 View 做铺垫。

主要内容有: View 的位置参数、 MotionEvent 和 TouchSlop 对象、VelocityTracker、GestureDetector 和 Scroller 对象。

下面来了解一些这些基础的概念吧。(部分内容摘自Android开发艺术探索)

 

1. View 的位置参数

View 的位置主要是由它的四个定点来决定,分别对应 View 的四个属性:top、left、right、bottom。

top:左上角纵坐标;bottom:右下角纵坐标;

left:左上角横坐标;right:右下角横坐标;

为了方便理解做了一张图:

查看源图像

从图中,可以清楚看出 View 的宽高:

width = right - left

height = bottom - top

 

了解到这里,那么这四个参数是如何得到的呢?如果看过源码,那么就能轻易的看到获取方式,如下:

left = getLeft();

right = getRight();

top = getTop();

bottom = getBottom();

 

2. MotionEvent 和 TouchSlop 对象

先看第一个参数: MotionEvent ( 触摸事件 )

当我们的手指接触屏幕后,会产生一系列的事件,比较常用的有下面几种:

ACTION_DOWN       手指刚接触屏幕

ACTION_MOVE       手指在屏幕移动

ACTION_UP         手指从屏幕松开

这三种相信都不陌生,当我们手指接触屏幕,然后再屏幕滑动一会再松开,会经历这么一个过程:

DOWN ==> MOVE ==> ... MOVE ==> UP

同时我们可以通过 MotionEvent 对象获取点击事件发生的 x 和 y 坐标。系统为我们提供了两组方法:

getX()/get()Y:相对于当前 View 左上角的 x 和 y 坐标;

getRawX()/getRawY():相对于手机屏幕左上角的 x 和 y 坐标;

 

再看另一个参数:TouchSlop (最小距离)

TouchSlop 是系统所能识别出的被认为是滑动的最小距离;

也就是说,当手指在屏幕滑动时,如果两次滑动间的距离小于这个值,那么系统不认为这是一次滑动操作;手机不同这个值也是不同的。

通过下面的方式便可以获取这个常量:

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

 

3. VelocityTracker ( 速度跟踪器 )

VelocityTracker 用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。

来看一下它的使用步骤:

//1.初始化 VelocityTracker 对象:
VelocityTracker mVelocityTracker = VelocityTracker.obtain();

//2.添加追踪:
mVelocityTracker.addMovement(event);

//3.计算速度:
//computeCurrentVelocity 第一个参数:时间为一秒,第二个参数:一秒运动了多少个像素
verTracker.computeCurrentVelocity(1000, ViewConfiguration.get(this).getMaximumFlingVelocity());
float velocityX = verTracker.getXVelocity(oneId);
float velocityY = verTracker.getYVelocity(oneId);

//4.回收:
mVelocityTracker.clear();
mVelocityTracker.recycle();

这里要理解速度的计算方法:

速度 = ( 终点位置 - 起点位置 ) /  时间段

 

了解使用步骤后,来看一下实际应用,就直接上代码了:

public class MainActivity extends AppCompatActivity {
    private VelocityTracker mVelocityTracker;//速度追踪器
    private int oneId;//第一个接触点id
    private static final String sFormatStr = "velocityX=%f\nvelocityY=%f";//格式化类型

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        /**
         * 1.初始化 VelocityTracker 对象
         */
        if (null == mVelocityTracker) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        /**
         * 2.添加追踪
         */
        mVelocityTracker.addMovement(event);
        final VelocityTracker verTracker = mVelocityTracker;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //求第一个触点的id,可能有多个触点,但至少一个
                oneId = event.getPointerId(0);
                break;

            case MotionEvent.ACTION_MOVE:
                /**
                 * 3.计算速度
                 */
                //第一个参数:时间为一秒,第二个参数:一秒运动了多少个像素
                verTracker.computeCurrentVelocity(1000, ViewConfiguration.get(this).getMaximumFlingVelocity());
                float velocityX = verTracker.getXVelocity(oneId);
                float velocityY = verTracker.getYVelocity(oneId);
                //格式化数据
                String info = String.format(sFormatStr, velocityX, velocityY);
                Log.e("=====速度为", info + "");
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                /**
                 * 4.回收
                 */
                if (mVelocityTracker != null) {
                    mVelocityTracker.clear();
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
}

上面就是使用 VelocityTracker 的全过程。

 

4.  GestureDetector ( 手势检测器 )

GestureDetector 是辅助检测用户的点击、滑动、长按、双击等行为。

下面说一下使用方法:

//1.初始化对象
private GestureDetector mGestureDetector;
mGestureDetector = new GestureDetector(new gestureListener());
mGestureDetector.setOnDoubleTapListener(new doubleTapListener());

//2.监听onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
    return mGestureDetector.onTouchEvent(event);
}

 

使用步骤非常简单,下面来看一下具体的使用方法:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    private GestureDetector mGestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mGestureDetector = new GestureDetector(new gestureListener());
        mGestureDetector.setOnDoubleTapListener(new doubleTapListener());
        //屏蔽了长按功能,使长按可以触发拖动效果;否则长按时不可以触发拖动效果
        mGestureDetector.setIsLongpressEnabled(false);

        TextView textView = findViewById(R.id.tv);
        textView.setOnTouchListener(this);
        textView.setFocusable(true);
        textView.setClickable(true);
        textView.setLongClickable(true);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return mGestureDetector.onTouchEvent(motionEvent);
    }

    //OnGestureListener监听
    private class gestureListener implements GestureDetector.OnGestureListener {
        @Override
        public boolean onDown(MotionEvent motionEvent) {
            Log.e("=====gestureListener", "按下");
            return false;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {
            Log.e("=====gestureListener", "按下,未松开和未拖动");
        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            Log.e("=====gestureListener", "单击");
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.e("=====gestureListener", "拖动");
            return false;
        }

        @Override
        public void onLongPress(MotionEvent motionEvent) {
            Log.e("=====gestureListener", "长按");
        }

        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.e("=====gestureListener", "快速滑动");
            return false;
        }
    }

    //OnDoubleTapListener监听
    private class doubleTapListener implements GestureDetector.OnDoubleTapListener {
        public boolean onSingleTapConfirmed(MotionEvent e) {
            //如果触发此方法,后面就不可以再紧跟一个单击
            Log.e("=====doubleTapListener", "单击");
            return true;
        }

        public boolean onDoubleTap(MotionEvent e) {
            Log.e("=====doubleTapListener", "两次连续单击");
            return true;
        }

        public boolean onDoubleTapEvent(MotionEvent e) {
            Log.e("=====doubleTapListener", "双击");
            return true;
        }
    }
}

 

这样便实现了对 TextView 控件的监听,可以看到上面的方法很多,比较常用的方法有五个:

onSingleTapUp (单击)、onFling (快速滑动)、onScroll(拖动)、onLongPress (长按)、onDoubleTapEvent (双击)。

 

5. Scroller ( 弹性滑动对象 )

Scroller 用于实现 View 的弹性滑动。

那么如何实现弹性滑动呢?很多地方都给出下面的经典代码:

    Scroller mScroller;

    mScroller = new Scroller(context);

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }

    private void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta, 0, 100);
        invalidate();
    }

在这里我也先给出经典的代码,想了解滑动的可以看这一篇:View的滑动

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值