滑動沖突問題,觸摸事件攔截處理


最近遇到了幾個關於滑動沖突的問題。問題的具體表現為:

 

  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM