zoukankan      html  css  js  c++  java
  • 滑动冲突问题,触摸事件拦截处理

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

    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同步滑动的效果,也可以斜着滑

    关于事件拦截的原理可以看:http://www.apkbus.com/blog-820900-61403.html

  • 相关阅读:
    jS Ajax 上传文件报错"Uncaught TypeError: Illegal invocation"
    layer实现关闭弹出层刷新父界面功能详解
    PHP开发APP接口简单签名全过程(二)实际测试
    PHP开发APP接口简单签名全过程(一)
    Laravel 避免 Trying to get property of non-object 错误的六种方法 [新增第六种 data_get]
    在PHP代码中将HTML代码原样输出的方式
    在使用 Laravel Eloquent 模型时,我们要判断取出的结果集是否为空,但我们发现直接使用 is_null 或 empty是无法判段它结果集是否为空的!!!
    使用layer的iframe层提交表单后,需要关闭当前的iframe层,然后刷新父页面的方法
    laravel中如何实现验证码验证及使用
    递归思想的由来
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5794867.html
Copyright © 2011-2022 走看看