在我前面的自定义裁剪窗口的代码中,我把裁剪的view放在了大的scrollview里,这样就出现了程序只能触发scrollview,无法操作我的裁剪窗口。所以我加了那篇博客下面最后两段代码。其实我遇到这个问题的时候是在一个scrollview里添加了一个Edittext,我限制了Edittext的高度,所以edittext里面的内容过多时会自己产生滚动条。但我怎么也无法触发edittext的滚动事件,后来查了资料就明白了。后来一直没对它做记录,现在对这个知识点做一个总结。

原文地址请保留http://www.cnblogs.com/rossoneri/p/3994662.html

老规矩,先推荐博客资料,毕竟从别人那学来的知识,好东西要分享:

[Android实例] [版主原创]ScrollView嵌套ScrollView

[Android实例] [版主原创]android之ScrollView里嵌套ListView

其实这俩是一个作者,好多人也转载这个(吐槽下那些只转载不留原文地址的,太恶心)。但讲的有点罗嗦了。。其实下面有更清楚的:

Android ScrollView嵌套ScrollView滚动的问题解决办法

这个是从老外那转来的,老外网站我这打不开了。。反正讲的很简单清楚:告诉你不建议嵌套scrollview,但嵌套了也没关系,再告诉你出现问题的原因,然后给你解决方案,就两行代码而已blabla。

最后就是理解原理的关键:解决问题代码方法的说明

android 事件处理机制之requestDisallowInterceptTouchEvent

一万个赞!

好了,如果上面的你看完了,也就基本弄明白了,到这里就可以结束了。


总结:

这种情况说简单点就是上层的view的onTouchEvent和下层view的onTouchEvent重叠了,系统无法判断你想activate哪个onTouchEvent,然后系统就很蛋疼,跑程序的时候上层动一下,下层动一下,结果哪一层都动不起来(还是有小幅度偏移的)。这就是view之间的事,不限于scrollview,listView,gridView,自定义view什么的,所以标题定的也有问题,说白了就是view的嵌套。但为了文章能被更多的搜索到,我就是不改标题(什么心态)。

“当有多个层级的View时,在父层级允许的情况下,这个action会一直向下传递直到遇到最深层的View。所以touch事件最先调用的是最底层View的onTouchEent”

注意,允许,怎么设置是否允许呢?另外运行程序的时候的确是明显的,下层view先动,上层view后动,估计默认下父层级都是允许把消息传到最下层的吧。

“如果View的onTouchEvent接收到某个touch action并作了相应处理,最后有两种返回方式return true和return false;return true会告诉系统当前的View需要处理这次的touch事件,以后的系统发出的ACTION_MOVE,ACTION_UP还是需要继续监听并接收 的,而且这次的action已经被处理掉了,父层的View是不可能触发onTouchEvent了”

了解一下onTouchEvent的返回值的用途

“所以每一个action最多只能有一个onTouchEvent接口返回true”

多层(>2)情况需要考虑一下

“如果return false,便会通知系统,当前View不关心这一次的touch事件,此时这个action会传向父级,调用父级View的onTouchEvent。 但是这一次的touch事件之后发出的任何action,该View都不会再接受,onTouchEvent在这一次的touch事件中再也不会触发,也就是说一旦View返回false,那么之后的ACTION_MOVE,ACTION_UP等ACTION就不会在传入这个View,但是下一次 touch事件的action还是会传进来的。”

这里不太明白。代码里return是在最后一行,所以会先执行前面的ACTION_*吧,return true的话,aiction执行之后再返回true,上层不再响应event可以理解,但false的话,他应该都执行过了啊?再给上层执行?

看了下源码,view的源码里onTouchEvent有一个int型的flag,在action触发前会做个判断,但自己复写方法的话。。。我怎么觉得好奇怪。。再想想。。这里面原理多呢。。

 public boolean onTouchEvent(MotionEvent event) {
final int viewFlags = mViewFlags; if ((viewFlags & ENABLED_MASK) == DISABLED) {
if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
return (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
} if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
} if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
...
break; case MotionEvent.ACTION_DOWN:
...
break; case MotionEvent.ACTION_CANCEL:
            ...
break; case MotionEvent.ACTION_MOVE:
...
break;
}
return true;
} return false;
}

“在父层级允许的情况下。假设不改变父层级的dispatch方法,在系统调用底层onTouchEvent之前会先调用父View的onInterceptTouchEvent方法判断,父层View是不是要截获本次touch事件之后的action。”

看到这里,前面的疑惑有点头绪,再看源码

明天画个流程图出来

“如果onInterceptTouchEvent返回了true,那么本次touch事件之后的所有action都不会再向深层的View传递,统统都会 传给负层View的onTouchEvent,就是说父层已经截获了这次touch事件,之后的action也不必询问 onInterceptTouchEvent,在这次的touch事件之后发出的action时onInterceptTouchEvent不会再次调 用,知道下一次touch事件的来临。如果onInterceptTouchEvent返回false,那么本次action将发送给更深层的View, 并且之后的每一次action都会询问父层的onInterceptTouchEvent需不需要截获本次touch事件。只有ViewGroup才有 onInterceptTouchEvent方法,因为一个普通的View肯定是位于最深层的View,touch事件能够传到这里已经是最后一站了,肯 定会调用View的onTouchEvent。”

这段大概看看吧,前面基本了解了。

“对于底层的View来说,有一种方法可以阻止父层的View截获touch事件,就是调用 getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的 action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也无法截获以后的action。”

最后的关键方法,就用这个方法即可实现功能~(但最好要先搞懂原理)

最后贴个最早发现这个问题的代码,scrollview里的edittext,touch子view就设置其属性true,touch父view就帮子view设置属性false即可~

     mEssay.setOnTouchListener(new View.OnTouchListener() {

             @Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
}); mScrollView.setOnTouchListener(new View.OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
mEssay.getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
});

[Android] (在ScrollView里嵌套view)重叠view里面的onTouchEvent的调用方法的更多相关文章

  1. Android 解决ScrollView下嵌套ListView进页面不在顶部的问题

    以下为整理: 方法1 刚开始还可以,后来再调试时就不行了. 为了解决scrollview和listview冲突  设置了listview的高度   结果进页面就不是在顶部了 . 解决方案1:Scrol ...

  2. Android -- 在ScrollView中嵌套ListView

    在做一个工程,这个工程的布局可以相当的复杂,最外面是ScrollView,在ScrollView里面有两个Listview,这下好了,布局出来了,放在机子上跑,卡得想死有木有,信息乱跑乱出现,表示非常 ...

  3. android 在一个scrollView里面嵌套一个需要滑动的控件(listView、gridView)

    package cn.via.dageeeOrderFood.widget; import android.content.Context; import android.graphics.Point ...

  4. android中ScrollView嵌套ListView或GridView显示位置问题

    Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...

  5. Android 在ListView中嵌套ListView的事件处理

    前天在工作中遇到在ListView中的Item需要用ListView来展现处理后的内容,然后就遇到了一个很头疼的问题,作为Item的ListView没法进行滑动,而且显示也不正常,只是显示几个子Ite ...

  6. 【Android】ScrollView+GridView 显示问题

    在使用Android的ScrollView里面嵌套GridView时,设置android:layout_height="wrap_content"属性,运行界面的效果不会出现全部数 ...

  7. ScrollView中嵌套ListView显示

    想要ScrollView中嵌套显示ListView 需要自定义ListView 并重写onMeasure方法 重新计算  heightMeasureSpec的高度 int newHeight = Me ...

  8. android之ScrollView里嵌套ListView(转)

    hi,大家好,研究完ScrollView嵌套ScrollView之后,本人突然又想研究ScrollView里嵌套ListView了. 如果还不知道ScrollView嵌套ScrollView是怎么实现 ...

  9. Android之ScrollView嵌套ListView冲突

    在ScrollView中嵌套使用ListView,ListView只会显示一行多一点.两者进行嵌套,即会发生冲突.由于ListView本身都继承于ScrollView,一旦在ScrollView中嵌套 ...

随机推荐

  1. scala中的一些特殊符号的意义

    1.作为“通配符”,类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就 ...

  2. android开发学习——day2

    简单了解了android stdio的操作方式,今天着手于探究活动(Activity) 了解了基本活动与手动创建活动的方法,了解了onCreate()方法,了解了创建和加载页面布局(layout) 新 ...

  3. Zookeeper--0300--java操作Zookeeper,临时节点实现分布式锁原理

    删除Zookeeper的java客户端有  : 1,Zookeeper官方提供的原生API, 2,zkClient,在原生api上进行扩展的开源java客户端 3, 一.Zookeeper原生API ...

  4. kafka主题管理

    若代理设置了 auto.create.topics.enable=true,这样还未创建topic就往kafka发送消息时, 会自动创建一个 ${num.partitions}个分区和{default ...

  5. DDA, Bresenham line's algorithm and Voxel Traversal used in the Grid-Accelerator in PBRT

        - DDA(Digital Differential Analyzer, 数值微分法) -    计算机图形学中,经常会遇到一些计算机中”经典“的问题.例如,如何利用计算机”离散“的特质,模拟 ...

  6. Selenium3自动化问题一:selenium3在火狐浏览器执行driver.quit()报错2052解决方案

    一:问题说明 最近用到selenium3在火狐浏览器中执行自动化脚本,每次执行到driver.quit()方法总是报错,报错日志如下: 二:解决方案 搜了一圈网上的资料,都说是火狐的问题,于是去到se ...

  7. [Golang] 第三方包应该如何安装--在线和离线

    一 在线安装 采用go get的方式安装import 的时候找不到对应的包看看pkg里面有没有 二 离线安装 redis客户端采用git clone的方法安装的话可以用以下方法 cd src git ...

  8. ruby中字符串转换为类

    最近有个需求,需要根据一个字符串当作一个类来使用,例如: 有一个字符串 “ChinaMag”,根据这个字符串调用 类 ChinaMag下的方法. 解决办法: 1. rails可以使用 constant ...

  9. 在使用Git提交代码的时候犯了个低级错误

    今天在使用git提交代码的时候,犯了个很低级的错误,按照一切流程当我add并commit提交代码,最后使用push到远程仓库, 接下来奇怪的事情发生了,push之后,查看远程仓库代码并没有发现提交记录 ...

  10. js设计模式总结1

    js设计模式有很多种,知道不代表会用,更不代表理解,为了更好的理解每个设计模式,对每个设计模式进行总结,以后只要看到总结,就能知道该设计模式的作用,以及模式存在的优缺点,使用范围. 本文主要参考张容铭 ...