滑动冲突问题,触摸事件拦截处理

Posted mb61b711907d5f4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滑动冲突问题,触摸事件拦截处理相关的知识,希望对你有一定的参考价值。

最近遇到了几个关于滑动冲突的问题。问题的具体表现为:



  1. ScrollView里嵌套了一个垂直的ListView或者RecycleView会出现滑动卡顿的问题。问题的原因是ScrollView的滑动事件与子View(ListView或者RecycleView)的滑动发生了冲突。


解决的方法是写一个自定义ScrollView拦截子View的滑动事件。自定义ScrollView代码见下:

public class MyScrollView extends ScrollView

    public MyScrollView(Context context)

        super(context);

   


    public MyScrollView(Context context, AttributeSet attrs)

        super(context, attrs);

   


    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr)

        super(context, attrs, defStyleAttr);

   




    @Override

    public boolean onInterceptTouchEvent(MotionEvent ev)


        return true;

   



  1. 这种情况下的另一种问题是ListView的setSecletion()方法会被ScrollView屏蔽,导致ListView无法实现跳到指定Item。

解决的办法可以是:计算指定item到顶部的距离,调用scrollTo(x,y)方法滑到指定位置,比较复杂。




  1. ScrollView里嵌套了一个水平的ListView或者RecycleView也会出现滑动卡顿或者划不动的问题。原因和1是一样的。

解决办法也是写一个自定义ScrollView,判断滑动的意图是垂直滑动还是水平滑动:

public class MyScrollView extends ScrollView 
public MyScrollView(Context context) 
super(context);
public MyScrollView(Context context, AttributeSet attrs) 
super(context, attrs);
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) 
super(context, attrs, defStyleAttr);
private int x, y;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) 
switch (ev.getAction()) 
case MotionEvent.ACTION_DOWN://按下y

x = (int) ev.getX();
y = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE://移动

int new_x = (int) ev.getX();
int new_y = (int) ev.getY();
//判断有水平滑动的意向

int move_x = Math.abs(new_x - x);//x轴滑动的距离

int move_y = Math.abs(new_y - y);//y轴滑动的距离

if (move_x > (move_y + 10))//10的偏移量

return false;//传递给字View

//                //判断有上下滑动的意向(用于字VIew是上下,parent是水平的)

// int move_x = Math.abs(new_x - x);//x轴滑动的距离

// int move_y = Math.abs(new_y - y);//y轴滑动的距离

// if (move_y > (move_x + 10))//10的偏移量

//

// return false;

//


break;
return super.onInterceptTouchEvent(ev);


利用事件拦截可以解决很多Bug,也可以实现很酷炫的功能,如https://github.com/SingleShadowBlade/ScrollDemo.git

这是一个ListView的Item可以水平滑动,并且和titlebar同步滑动的效果,也可以斜着滑



以上是关于滑动冲突问题,触摸事件拦截处理的主要内容,如果未能解决你的问题,请参考以下文章

Android滑动事件冲突(上)

处理滑动冲突

Android事件的分发拦截和执行

Android——滑动事件冲突解决

Android点击事件和滑动冲突解决

Android YouTube Player API Fragment无法手动处理触摸事件