开发笔记:解决安卓GestureOverlayView手势和ListView点击事件、文本框获取焦点冲突的问题
要解决这个问题,首先要弄清楚几个问题:
1、onThouch事件的触发原理是怎样的?
2、GestureOverlayView的绘制手势的事件是在什么时候触发的?
3、父子嵌套的控件触发事件的顺序是怎样的?
4、父子控件获取焦点的顺序是怎样的?
第一个问题,安卓中任何控件的onThouch事件触发的时候,都经过了以下过程:
public boolean dispatchTouchEvent(MotionEvent ev) ,该方法如果返回true,则事件在该位置被消费掉,不再向下传递,返回false则继续传递至
public boolean onInterceptTouchEvent(MotionEvent ev)这个方法,该方法是事件拦截器,如果返回true,则触发该控件的onThouch事件,否则就将事件传递给该控件的子控件,
public boolean onTouchEvent(MotionEvent ev),返回true的话就消费掉该事件,返回false就传递到该控件的父控件的onThouch事件
在网上找到一个图片,能简洁明了的反映以上关系:
第二个问题,查看GestureOverlayView源码可知道,手势绘制的监听触发时间是在dispatchTouchEvent(MotionEvent ev)这个事件中就完成的,所以只要有触摸屏幕的动作,就必然会被它先消费掉,这也是手势事件和其他控件冲突的根本原因~源码如下:
@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {if (isEnabled()) {final boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null &&mCurrentGesture.getStrokesCount() > 0 && mPreviousWasGesturing)) &&mInterceptEvents;processEvent(event);if (cancelDispatch) {event.setAction(MotionEvent.ACTION_CANCEL);}super.dispatchTouchEvent(event);return true;}return super.dispatchTouchEvent(event);}private boolean processEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:touchDown(event);invalidate();return true;case MotionEvent.ACTION_MOVE:if (mIsListeningForGestures) {Rect rect = touchMove(event);if (rect != null) {invalidate(rect);}return true;}break;case MotionEvent.ACTION_UP:if (mIsListeningForGestures) {touchUp(event, false);invalidate();return true;}break;case MotionEvent.ACTION_CANCEL:if (mIsListeningForGestures) {touchUp(event, true);invalidate();return true;}}return false;}
基于这个原因,可能很多人会考虑通过重写GestureOverlayView控件来解决冲突问题,我也试过了,但是依然不能解决较为复杂的问题,所以在次就不再赘述了。
第三个问题,借用一篇博客来说明问题,在此感谢博主 @浅秋http://blog.csdn.net/hyp712/article/details/8777835(博文写的很详细)
借用第三个问题,第四个问题就迎刃而解了,可以简单的理解为,正常情况下,最内层的控件是最先获取焦点的,
最外层的是最后获取焦点的;但是最外层的获取焦点的优先级是最高的,一旦它决定拦截并消费事件,那么它的子控件就不能再获取该事件;
解决冲突的方法:
我的需求是在一个ListView页面启用手势功能,
用户如果画了手势,则根据手势内容做不同的反应,但是手势不能影响ListView的滚动、点击、选中的操作;
ListView中包含文本框;如果点击的是文本框,不能影响文本框获取焦点进行编辑;
我重写GestureOverlayView的时候解决了前2个需求,但是文本框死活获取不了焦点;
布局文件如下,需要说明是,因为之前是通过重写来做的,但是最后没解决,于是重写的文件直接调用了super,等于没重写:
<ListView
android:id="@+id/list_aj"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:longClickable="true"
/><TextView
android:id="@+id/textViewModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
/><EditText
android:id="@+id/textViewValueModel"
android:layout_width="300dp"
android:layout_height="40dip"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_marginLeft="110dip"
android:textSize="17sp"
android:background="@null"
android:inputType="text"
android:focusable="false"
android:visibility="gone"
/><ImageView
android:id="@+id/imageViewModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:contentDescription="@string/descTask"
android:layout_centerVertical="true"/><com.zbtc_it.tcis.Util.MGestureOverlayView
calss="com.zbtc_it.tcis.Util.MGestureOverlayView"
android:id="@+id/gesture"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
</com.zbtc_it.tcis.Util.MGestureOverlayView>
重写的时候,我用MGestureOverlayView包含了ListView,
但是后来一想,因为MGestureOverlayView每次都会最先拦截,并且它必然会消费事件,所以这样肯定是不行的,
于是就换成并列的,解决方法就是,在MGestureOverlayView的onThouch事件中,手动赋予ListView的事件源,代码如下
overlays = (MGestureOverlayView) layout.findViewById(R.id.gesture);
overlays.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
overlays.setFadeOffset(1000);// 多笔画2笔之间的时间间隔overlays.setOnTouchListener(new View.OnTouchListener() {@Override
public boolean onTouch(View v, MotionEvent event) {
itemListView.dispatchTouchEvent(event);//赋予ListView事件源
return false;//消费掉事件
}
});
同时重写ListView的onInterceptTouchEvent方法,让其直接返回false
(这步好像不是必须的,忘记了 >_< ,默认的貌似就是返回false)
开发笔记:解决安卓GestureOverlayView手势和ListView点击事件、文本框获取焦点冲突的问题相关推荐
- 在移动端H5开发中(关于安卓端position:fixed和position:absolute;和虚拟键盘冲突的问题,以及解决方案)
在移动端H5开发中(关于安卓端position:fixed和position:absolute:和虚拟键盘冲突的问题,以及解决方案) 参考文章: (1)在移动端H5开发中(关于安卓端position: ...
- android+点击屏幕隐藏键盘,Android点击EditText文本框之外任何地方隐藏键盘的解决办法...
1,实现方法一: 通过给当前界面布局文件的父layout设置点击事件(相当于给整个Activity设置点击事件),在事件里进行键盘隐藏 android:id="@+id/traceroute ...
- fastclick.js解决移动端(ipad)点击事件反应慢问题
fastclick.js解决移动端(ipad)点击事件反应慢问题 参考文章: (1)fastclick.js解决移动端(ipad)点击事件反应慢问题 (2)https://www.cnblogs.co ...
- (转)完美解决 Android WebView 文本框获取焦点后自动放大有关问题
完美解决 Android WebView 文本框获取焦点后自动放大问题 前几天在写一个项目时,要求在项目中嵌入一个WebView 本来很快就完成了,测试也没有问题.但发给新加坡时,他们测试都会出现文本 ...
- 完美解决 Android WebView 文本框获取焦点后自动放大问题
前几天在写一个项目时,要求在项目中嵌入一个WebView 本来很快就完成了,测试也没有问题.但发给新加坡时,他们测试都会出现文本框聚焦时,网页面会放大(他们用三星手机测试的) 网上查了好久参考他的方法 ...
- 安卓开发笔记(十):升级ListView为RecylerView的使用
概述 RecyclerView是什么 从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活.Recycle ...
- ListView点击事件失效
记录下自己所犯的错误,在写ListView的点击事件时OnItemClickListener,onItemClick方法没有执行,导致ListView条目点击事件失效,检查发现百度上有很多不同的答案, ...
- Listview点击事件
listview = (ListView) findViewById(R.id.listview); // 填充data数据 data = new ArrayList<String>(); ...
- Android点击EditText文本框之外任何地方隐藏键盘的解决办法
通过给当前界面布局文件的父layout设置点击事件(相当于给整个Activity设置点击事件),在事件里进行键盘隐藏 <LinearLayout xmlns:android="http ...
最新文章
- Android Log 打印不出来
- 消息队列 策略_消息队列技术点梳理(思维导图版)
- 我的vscode配置 利用Settings Sync一键安装
- WPF实现统计图(饼图仿LiveCharts)
- 团队作业7——Beta版本冲刺计划及安排
- 图像处理-图像增强(三)
- iOS动画 三维透视投影 m34
- html怎么把图片左移_css如何向左移动图片
- 面向对象编程介绍,类和对象
- 立创EDA极速入门(1)——熟悉PCB和立创EDA基本操作
- vmware win7虚拟机安装vmtools坑
- 域名可以用多久_域名保护期限是多久?过期了域名还能用吗
- PhoneGap的移动开发框架
- iSCSI target initiator
- switch日版有中文吗_原神Switch日版可以玩吗
- Python中inplace参数
- mysql 挑战握手协议_[中文协议]PPP挑战握手认证协议(CHAP)
- android框架服务 恶意软件,Android平台各类恶意软件及病毒概览
- 多少鸿蒙冰心换无间,现阶段法宝及相关道具获取途径汇总
- 判断OOBE 完成状态
热门文章
- Convergence of probability measure P. Billingsley 笔记:Chapter 1-12 (正在进行中)
- Java使用poi操作excel注意事项
- docker离线安装mysql镜像
- The bean ‘xxx.FeignClientSpecification‘ could not be registered
- ios设计组件_在ios上实现设计系统组件
- 让工作节奏慢一点, 再简单的工作也能做出大成就
- JavaWeb JavaScript
- USB 4.0有什么用,和雷电3有什么区别,USB 4.0什么时候上市
- 【个人学习用】利用随机森林学习调参总结
- 《真还传》罗永浩的6亿债还完了?!