Android ScrollView嵌套ScrollView,并且嵌套的ScrollView超过屏幕部分

    xiaoxiao2025-04-07  14

    问题:我在ScrollView里面嵌套了一个ScrollView,嵌套的ScrollView超出了屏幕显示部分,需要向下滑动才能看到,当滑动下去找到嵌套的ScrollView时,滑动时并不能触发它的onTouch()事件。

    Android的Touch传递机制,这里不详细介绍了,有想了解的,推荐http://blog.csdn.net/chunqiuwei/article/details/41084921,和http://www.infoq.com/cn/articles/android-event-delivery-mechanism/ 这两篇写得都不错,可以借鉴一下。

    解决思路: 1. 先是参考的http://mengsina.iteye.com/blog/1707464这一篇文章,主要利用了在onTouch()事件里面写v.getParent().requestDisallowInterceptTouchEvent(true); 这种方法,让父ScrollView不拦截Touch事件,自己来处理。

    亲自实验了这个方法,当嵌套的ScrollView不超出屏幕时是可以用的,可是当嵌套的ScrollView超出屏幕时,就不可以了。 代码如下,当touch子ScrollView时,打印出”触摸了第2个ScrollView”,然而并没有成功,结果在后面,全都是打印的”触摸了第1个ScrollView”: MainActivity.java->onCreate():

    //父ScrollView svParent = (ScrollView) findViewById(R.id.sv_parent); svParent.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { ViewParent parent = findViewById(R.id.sv_child).getParent(); parent.requestDisallowInterceptTouchEvent(false); //允许父类截断 System.out.println("触摸了第1个ScrollView"); return false; } }); //子ScrollView svChild = (ScrollView) findViewById(R.id.sv_child); svChild.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { ViewParent parent1 = v.getParent(); parent1.requestDisallowInterceptTouchEvent(true); //不允许父类截断 System.out.println("触摸了第2个ScrollView"); return false; } });

    结果截图:

    从这个结果来看,Touch事件,没有传递到嵌套的ScrollView上来,应该是被上层的ViewGroup截获,或者是传下去被下面的View消费掉了,没再传上来。

    2.接下来,就是想让这个嵌套的ScrollView截获传递过来的Touch事件,不再分发下去了。所以想到重写ScrollView的onInterceptTouchEvent(),让它返回true,让这个嵌套的ScrollView截获这个Touch事件(注意:onInterceptTouchEvent()返回true,表示截获这个Touch事件;返回false,表示不搭理这个Touch事件)。

    自定义ScrollView CustomScrollView.java:

    package com.tudou.scrollviewnested; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /** * Created by Administrator on 2016-08-14. */ public class CustomScrollView extends ScrollView { public CustomScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { System.out.println("第2个ScrollView:dispatchTouchEvent"); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { System.out.println( "第2个ScrollView: onInterceptTouchEvent: "); // return super.onInterceptTouchEvent(ev); boolean flag = false; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: flag = super.onInterceptTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: flag = true; break; } return flag; } @Override public boolean onTouchEvent(MotionEvent ev) { System.out.println( "第2个ScrollView: onTouchEvent: "); return super.onTouchEvent(ev); } }

    在上面的代码里面可以看到,onInterceptTouchEvent()函数,我让它直接返回了true。再看一下结果,看看调用顺序哈。 结果截图:

    从结果上可以看出这几个函数的调用顺序: 1. 是CustomScrollView里面的dispatchTouchEvent() 2. 是CustomScrollView里面的onInterceptTouchEvent() 3. 是MainActivity里面的svChild.setOnTouchListener->onTouch()事件 4. 是CustomScrollView里面的onTouchEvent()

    ^_^ OK~~~~~~~

    转载请注明原文地址: https://ju.6miu.com/read-1297829.html
    最新回复(0)