文档章节

Android ViewPager和ScrollView嵌套滚动问题解决方案

冰珊孤雪
 冰珊孤雪
发布于 2015/04/22 21:18
字数 802
阅读 12411
收藏 16

问题描述:

  1. 我的嵌套是ViewPager-->ScrollView-->ViewPager.


  2. 首先最里面的ViewPager水平滚动时总是会触发最外层的ViewPager滚动,看了网上很多的解决办法基本上是一样的,需要自定义ViewPager。

import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。
 * Created by Administrator on 2015/4/20.
 */
public class HorizontalInnerViewPager extends ViewPager {
    /** 触摸时按下的点 **/
    PointF downP = new PointF();
    /** 触摸时当前的点 **/
    PointF curP = new PointF();


    public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }
    public HorizontalInnerViewPager(Context context) {
        super(context);

        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);//default
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //每次进行onTouch事件都记录当前的按下的坐标
        curP.x = ev.getX();
        curP.y = ev.getY();

        if(ev.getAction() == MotionEvent.ACTION_DOWN){
            //记录按下时候的坐标
            //切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变
            downP.x = ev.getX();
            downP.y = ev.getY();
            //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if(ev.getAction() == MotionEvent.ACTION_MOVE){
            //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
                getParent().requestDisallowInterceptTouchEvent(true);
        }

        return super.onTouchEvent(ev);
    }

}


3.解决了上面的问题,又出现了新的问题,当最里面的ViewPager垂直滚动时外层的ScrollView并不会滚动,解决方法如下:

import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;

/**
 * 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。
 * Created by Administrator on 2015/4/20.
 */
public class HorizontalInnerViewPager extends ViewPager {
    /** 触摸时按下的点 **/
    PointF downP = new PointF();
    /** 触摸时当前的点 **/
    PointF curP = new PointF();

    /** 自定义手势**/
    private GestureDetector mGestureDetector;

    public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }
    public HorizontalInnerViewPager(Context context) {
        super(context);

        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);//default
        //当拦截触摸事件到达此位置的时候,返回true,
        //说明将onTouch拦截在此控件,进而执行此控件的onTouchEvent
//        return true;
        //接近水平滑动时子控件处理该事件,否则交给父控件处理
//        return mGestureDetector.onTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //每次进行onTouch事件都记录当前的按下的坐标
        curP.x = ev.getX();
        curP.y = ev.getY();

        if(ev.getAction() == MotionEvent.ACTION_DOWN){
            //记录按下时候的坐标
            //切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变
            downP.x = ev.getX();
            downP.y = ev.getY();
            //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if(ev.getAction() == MotionEvent.ACTION_MOVE){
            float distanceX = curP.x - downP.x;
            float distanceY = curP.y - downP.y;
            //接近水平滑动,ViewPager控件捕获手势,水平滚动
            if(Math.abs(distanceX) > Math.abs(distanceY)){
                //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰
                getParent().requestDisallowInterceptTouchEvent(true);
            }else{
                //接近垂直滑动,交给父控件处理
                getParent().requestDisallowInterceptTouchEvent(false);
            }
        }

        return super.onTouchEvent(ev);
    }

    private class XScrollDetector extends GestureDetector.SimpleOnGestureListener{
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//            return super.onScroll(e1, e2, distanceX, distanceY);

            //接近水平滑动时子控件处理该事件,否则交给父控件处理
            return (Math.abs(distanceX) > Math.abs(distanceY));
        }
    }

}



© 著作权归作者所有

冰珊孤雪
粉丝 7
博文 28
码字总数 4129
作品 0
苏州
私信 提问
加载中

评论(2)

坐在坟头调戏鬼

引用来自“IamOkay”的评论

第二种实现不显示把把,ViewPager本身可以垂直滚动的,为何还要嵌套ScrollView啊
viewpager下面还有很多其他布局呢
IamOkay
IamOkay
第二种实现不显示把把,ViewPager本身可以垂直滚动的,为何还要嵌套ScrollView啊
Android NestedScrollView/ScrollView包裹ViewPager自适应高度

Android NestedScrollView/ScrollView包裹ViewPager自适应高度 当Android的NestedScrollView/ScrollView这类滚动View包裹ViewPager时候,ViewPager中的Fragment包含的又是一系列高度值不固定...

zhangphil
2018/05/12
0
0
android ScrollView 嵌套ViewPager ,ViewPager又嵌套ScrollView,事件冲突

android 开发工具:android studio 问题:实现一个类似淘宝之前的一个上拉查看商品详情功能,但是我们这个嵌套关系是这样的,ScrollView ——>LinearLayout——>ViewPager——>ScrollView,现...

刘超亚
2017/05/26
205
0
scrollview嵌套viewpager

scrollview嵌套viewpager (左右滑动的) viewpager自适应高度失效了。。。怎么解决scrollview里面viewpager的高度自适应问题

默默灬
2016/04/21
198
0
Android viewPager预加载的问题

最近做的东西,viewpager中嵌套了一个srollview,因为scrollview中text内容量不同,导致有些可以滑动,有些不需要滑动,viewpager的预加载使onmeasure最后测量的是当前显示页旁边的,所以当前...

deadPool
2017/02/08
259
1
android里scrollview里嵌套viewpager后,scrollview的ontouch事件里不能获得ACTION_DOWN

代码在 http://git.oschina.net/addjava/scrollviewPullDown.git 下拉scrollview可以刷新 android里scrollview里嵌套viewpager后,scrollview的ontouch事件里不能获得ACTION_DOWN 求指教........

老鼠盘根
2013/08/22
2.2K
1

没有更多内容

加载失败,请刷新页面

加载更多

c++ 内联函数调用快的原因

见图片分析

天王盖地虎626
41分钟前
3
0
JS--function

一、声明提前(hoist) 在js程序开始执行前,引擎会查找所有var声明的变量和function声明的函数,集中到当前作用域顶部集中创建,赋值留在原地 二、三种创建函数的方式 1、声明方式创建函数-...

wytao1995
今天
5
0
微服务之间调用控制器注解类型的差异

今天在一个业务服务通过Feign调用文件服务上传文件时遇到了几个问题: 1. 提示http请求头过大的问题; 此时需要修改bootstrap.yml,加入 server: max-http-header-size: 10000000 用以放大...

不再熬夜
今天
7
0
用 4G 工作是什么体验

七月开始,因为工作原因,在公司附近租了个住处,方便工作。离公司近了,感觉就是不一样,之前每天 5:30 就要起床赶地铁,现在可以睡到自然醒,一看才 7 点,悠闲的起床洗漱,踱步到公司,都...

zzxworld
今天
6
0
sonar报错volatile

问题发生 原先代码如下: //认证授权码private static volatile String AUTHORIZATION_CODE = "init"; git push 之后,sonar认为这是个bug检测报告截图如下: 分析排查 解释说明: Markin...

开源小菜鸟2333
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部