zoukankan      html  css  js  c++  java
  • PullToRefreshListView中嵌套ViewPager滑动冲突的解决

    PullToRefreshListView中嵌套ViewPager滑动冲突的解决

    最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情况,ViewPager 作为头部添加到ListView中,发先ViewPager在滑动过程中流畅性太差几乎很难左右滑动。在网上也看了很多大神的介绍,看了ViewPager的源码。其实思路很简单,只不过没有看到有教完整的说明,为了帮转像我这样的green hand 少走弯路,将过程整理下。大神自动略过~_~:

    滑动冲突的解决大概要处理的问题无非是事件分发,事件拦截,和事件的处理,关于这部分内容大家可以在网上查看相关的资料,基本原理比较容易理解。有了这部分内容做铺垫。下面正式进入正题。

    解决这个问题有两种实现方式

    一 首先采取了给ViewPager设置监听的方式

    vPager.setOnPageChangeListener(new OnPageChangeListener() {
                @Override
                public void onPageSelected(int arg0) {
                    //该方法是ViewPager滑动结束后,页面别选定后调用此方法
                    /*在ViewPager滑动结束后需要通知父容器(ListView)可以
                     * 对后续的事件进行适当的处理了(包括自身事件的拦截)*/
                    lsv.requestDisallowInterceptTouchEvent(false);
                }
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    //该方法是ViewPager滑动时调用此方法
                    /*在ViewPager滑动时需要通知父容器(ListView)不要拦截,
                    也就是说此事件交给ViewPager处理*/
                    lsv.requestDisallowInterceptTouchEvent(true);   
                }
                @Override
                public void onPageScrollStateChanged(int arg0) {
                    //该方法是ViewPager滑动状态发生变化时调用此方法
                    //这里暂时不要进行相关的操作。
                }
    });


    这种方式可以解决ViewPager左右滑动与listView的冲突问题,但是会有一个问题,此时在VIewPager上的下拉事件也被ViewPager接收,只能在ViewPager下边下拉才能实现PullToRefreshListView 的下拉刷新效果。 

    这里写图片描述

    如果不需要下拉刷新,普通的ListView 通过上面的方式完全可以达到预期的效果

    二 重写ViewPager的disPatchTouchEvent方法

    基本思路就是要重写ViewPager的disPatchTouchEvent方法,通过比较x、y轴的移动距离,决定事件是否自己进行处理。

    package com.ccq.tuangou.myview;
    
    import android.content.Context;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    
    public class MyViewPager extends ViewPager {
        float mDownX;
        float mDownY;
        public MyViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //DOWN 事件的时候记录下当前的xy左标
                mDownX=ev.getX();
                mDownY=ev.getY();
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                /*MOVE 事件后计算x轴y轴的移动距离 ,如果x轴移动距离大于y轴,
                那么该事件有ViewPager处理,否则交给父容器处理*/
                if(Math.abs(ev.getX()-mDownX)>Math.abs(ev.getY()-mDownY)){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }else{
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            default:
                break;
            }
            return super.dispatchTouchEvent(ev);
        }
    }
  • 相关阅读:
    JAVA中的浅拷贝与深拷贝
    Spring异步-@Async注解
    Spring 事务传播行为的使用
    DecimalFormat的使用
    Java编码问题原因以及解决
    Spring
    [TimLinux] docker CentOS7 入门——容器(1)
    [TimLinux] asciinema Linux终端录制工具嵌入私有web中
    [TimLinux] docker CentOS7安装docker-ce最新版
    [TimLinux] systemd 精通CentOS7系统启动systemd
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7326553.html
Copyright © 2011-2022 走看看