您的位置:首页 > 移动开发 > Android开发

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

2016-08-14 14:53 260 查看
问题:我在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~~~~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android ScrollView