二、自定义View ( 事件处理 )

一、MotionEvent (触摸事件)

手指接触屏幕的系列动作监听

● ACTION_DOWN : 按下

● ACTION_MOVE : 移动

● ACTION_UP : 离开

例如:

手指点击后松开:ACTION_DOWN -->ACTION_UP
手指点击后滑动2次离开 :ACTION_DOWN --> ACTION_MOVE --> ACTION_MOVE -->ACTION_UP

获取点击事件发生的坐标:

1、getX,getY:获取点击事件位于当前View的左上角的x,y的坐标
2、getRawx,getRawy : 获取点击事件相对于屏幕左上角的x和y的坐标

二、TouchSlop (系统能识别的最小滑动距离)

概念:系统识别的最小滑动距离。每一个手机的值是不同的

意义:提高用户体验,过滤无效的操作。

获取方法 : ViewConfiguration.get(getContext()).getScaledTouchSlop()

源码体现:在源码中,它在frameworks/base/core/res/res/values/cofing.xml

8dp

也就是说,这一款手机在定义的时候,它的最小滑动距离 8dp(设备不同,这个值也不同)

三、VelocityTracker (滑动速度)

1、概念:追踪手指滑动的速度,包括水平方向和竖直方向

2、使用:在View的onTouchEvent方法监听

@Override
public boolean onTouchEvent(MotionEvent event) {

//在用户触摸事件里面,监听滑动速度
VelocityTracker velocityTracker=VelocityTracker.obtain();
velocityTracker.addMovement(event);
//获取滑动速度的值如下
//设置监听1秒内,用户滑动的像素数
velocityTracker.computeCurrentVelocity(1000);
//水平滑动速度
int Xvelocity= (int) velocityTracker.getXVelocity();
//垂直滑动速度
int Yvelocity= (int) velocityTracker.getYVelocity();
return super.onTouchEvent(event);
}

3、滑动速度计算:

速度=(终点-起点)/ 时间
速度= 滑动的像素数量 / 时间

4、注意:

1、得出的速度有可能为负数,用户向左滑动为负数,向右为正数,上下同理
2、当不用的时候,需要清除并且回收,执行如下方法:
velocityTracker.clear();
velocityTracker.recycle();

四、GestureDetector(手势识别)

概念:用于辅助识别:单击,滑动,长按,双击等事件。
用途:根据喜好来使用,可以不用这个类,在onTouchEvent中自己去判断用户行为。
建议:滑动类型在onTouchEvent中直接判断,如果是双击类型建议使用GestureDetector

1、创建方法:

//辅助判断用户手势行为
GestureDetector gestureDetector=new GestureDetector(mcontext,this);

//解决长按屏幕后无法拖动的情况
gestureDetector.setIsLongpressEnabled(false);

//监听双击类型事件
gestureDetector.setOnDoubleTapListener(this);

2、具体方法:

// 手指轻轻触摸屏幕的一瞬间
public boolean onDown(MotionEvent motionEvent)

// 手指触摸屏幕后,没有松开。
public void onShowPress(MotionEvent motionEvent)

//单击行为
public boolean onSingleTapUp(MotionEvent motionEvent)

//拖动行为,也可以理解为滑动行为
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1)

//长按
public void onLongPress(MotionEvent motionEvent)

//快速滑动行为
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1)

//严格的单击行为,不能是双击的第一次点击
public boolean onSingleTapConfirmed(MotionEvent motionEvent)

//双击,不能和onSingleTapConfirmed共存
public boolean onDoubleTap(MotionEvent motionEvent)

//双击行为
public boolean onDoubleTapEvent(MotionEvent motionEvent)

五、Scroller(平滑过渡滑动效果)

概念:弹性滑动对象,用于实现View的平滑过渡滑动效果
优点: 单纯的使用scrollTo或者是scrollBy方法来实现滑动是瞬间完成的,没有过渡效果
注意: 弹性滑动需要scroller和view的computeScroll方法配合使用

具体代码(写法是固定的):

1、View的构造方法中,创建Scrolle对象

mscroller=new Scroller(mcontext);

2、重写View的computeScroll方法

@Override
public void computeScroll() {

if (mscroller.computeScrollOffset())
{
scrollTo(mscroller.getCurrX(),mscroller.getCurrY());
//刷新View
postInvalidate();
}

}

3、编写smoothScrollTo方法(非系统方法,手工编写)

private void smoothScrollTo(int destX,int destY)
{
int scrollX=getScrollX();
int delta=destX-scrollX;
mscroller.startScroll(scrollX,0,delta,0,10000);
//刷新View
invalidate();
}

六、View的滑动

1、实现View滑动的三种方式

● 使用scrollBy和scrollTo来实现
● 通过动画给View编写平移效果(View没有太多的交互性,某些有交互的用动画实现会有点问题)
● 改变View的LayoutParams使用View重新布局来实现滑动(适用于有交互性的view)

2、三种方式的优缺点

scrollBy和scrollTo :操作简单,适合对view的内容进行滑动
动画:操作简单,只要适用没有交互的view的滑动效果
改变LayoutParams参数: 操作相对复杂,适用于有交互的view

改变View的LayoutParams示例代码:

TextView tv= (TextView) findViewById(R.id.tv);
ViewGroup.MarginLayoutParams marginLayoutParams=
(ViewGroup.MarginLayoutParams) tv.getLayoutParams();
marginLayoutParams.width+=100;
marginLayoutParams.leftMargin+=100;
tv.requestLayout();
//或者tv.setLayoutParams(marginLayoutParams);

七、 onTouchEvent 和 onInterceptTouchEvent() 区别

实际场景(解决滑动冲突):
详情链接:https://juejin.im/entry/5928bfa92f301e0057d4f414
详情链接:http://blog.csdn.net/lvxiangan/article/details/9309927

1、只有继承ViewGroup才有onInterceptTouchEvent()方法,继承View没有这个方法。
2、两者都是基于事件的处理,但是onInterceptTouchEvent偏向预处理。
3、onInterceptTouchEvent(),是从父控件往子控件传递的处理

注意 :返回值为true,则事件由当前控件(父控件处理),不会传递到子控件
返回值为false, 则事件由子控件处理,可以在子控件的onInterceptTouchEvent处理

4、onTouchEvent(),是从子控件向父控件传递的处理

注意 :返回值为true,自己处理
返回值为false, 向上传递,交给父控件处理

你可能感兴趣的:(二、自定义View ( 事件处理 ))