在我前面的自定义裁剪窗口的代码中,我把裁剪的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. (转)Python 实现双向链表(图解)

    原文:https://blog.csdn.net/qq490691606/article/details/49948263 Python 实现双向链表(图解)双向链表双向链表也叫双链表,是链表的一种, ...

  2. IIS 站点部署多级域名

    当站点的规模达到一定程度,往往会对业务进行拆分,部署到一台服务器的不同站点,,而一个域名(顶级域名)只能绑定一个站点(核心站点),这个时候就通过给顶级域名创建子域名的方式(理论上一个顶级域名可以绑定5 ...

  3. Jenkins-pipeline的实现步骤

    jenkins实现持续集成 搭建jenkins环境,安装插件 建立pipeline公用类库,文件夹vars,默认的 添加.groovy文件,可以由以下几个类库组成 dockerImageBuild 负 ...

  4. AJAX(Jquery)

    一)jQuery常用AJAX-API 目的:简化客户端与服务端进行局部刷新的异步通讯 (1)取得服务端当前时间 简单形式:jQuery对象.load(url) 返回结果自动添加到jQuery对象代表的 ...

  5. Linux-(watch,at,crontab)

    watch命令 1.命令格式: watch  [参数]  [命令] 2.命令功能: 可以将命令的输出结果输出到标准输出设备,多用于周期性执行命令/定时执行命令. watch可以帮你监测一个命令的运行结 ...

  6. WPF设置控件获取键盘焦点时的样式FocusVisualStyle

    控件获取焦点除了用鼠标外,可以通过键盘来获取,比如Tab键或者方向键等,需要设置控件获取键盘焦点时的样式,可以通过设置FrameworkElemnt.FocusVisualStyle属性, 因为几乎所 ...

  7. 安装mysql时报Missing required library libcc.dll 126

    Missing required library libcc.dll 126 安装一个Cygwin就好了

  8. 深入出不来nodejs源码-内置模块引入初探

    重新审视了一下上一篇的内容,配合源码发现有些地方说的不太对,或者不太严谨. 主要是关于内置模块引入的问题,当时我是这样描述的: 需要关注的只要那个RegisterBuiltinModules方法,从名 ...

  9. ASP.NET MVC应用程序播放AVI视频

    前面Insus.NET实现一系列在MVC应用程序播放SWF, FLV, WMV, RM, RMVB视频.每篇使用不同的方法方式,大同小异.这篇中,为了MVC应用程序播放AVI视频,用纯M, V, C来 ...

  10. SQL语句大全从基础到熟练(不含数据库高端操作)日常用户 三、

    前言 昨天晚上回家忘记带钥匙导致在楼下站街三小时,鬼天气热的不要不要的然后我就在车里坐了会之后就.....zzZZ,哈哈睡的挺香的毕竟累了一天了 上两篇文章都是介绍的语法语句,本篇文章介绍下函数的使用 ...