问题分析
Edittext 在 ListView 的 item 中,没有其他的类似焦点冲突问题,在没有头绪的情况下,先从源码开始分析问题根源,Edittext 关于处理长按事件的部分是继承 TextView 的,所以先看 TextView 的 performLongClick 方法
TextView 的 performLongClick 方法源码:
|
|
可以发现 TextView 的 performLongClick 方法主要分为两步:一、调用 View 的 performLongClick;二、调用 Editor 的 performLongClick
Editor 的 performLongClick 方法源码:
|
|
分析 Editor 的 performLongClick 方法,可以发现如果传入的参数 handled 为 true,那么 performLongClick 相当于什么都没做。而从代码中可以看出 Editor 的这个方法就是用来显示复制、粘贴的上下文菜单的。
所以在 TextView 的 performLongClick 中,调用 View 的 performLongClick 返回为 true 的话,调用 Editor 的 performLongClick 就什么都没做,也就不会显示复制、粘贴的上下文菜单了。
断点调试发现果然 super.performLongClick() 返回为 true,所以接下来就要分析为什么会返回 true。
View 的 performLongClick 方法源码:
|
|
View 的 performLongClick 方法就是先调用 onLongClickListener,如果返回为 false,则调用 showContextMenu 方法,因为 Edittext 没有设置 onLongClickListener,所以肯定会调用 showContextMenu 方法
继续断点调试,下面是主要调试信息:
at android.widget.AbsListView.showContextMenuForChild(AbsListView.java:3006)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:657)
at android.view.View.showContextMenu(View.java:4507)
at android.view.View.performLongClick(View.java:4468)
at android.widget.TextView.performLongClick(TextView.java:8354)
at android.view.View$CheckForLongPress.run(View.java:18401)
继续看 AbsListView 的 showContextMenuForChild 方法源码:
|
|
如果 onItemLongClickListener 不为空的话,会先调用它,如果返回 false 再继续调用 parent 的 showContextMenuForChild 方法。
再查看我的代码,发现 ListView 有设置 onItemLongClickListener,而且 onItemLongClick 方法最后一定会 return true。
- 原因分析
通过以上的工作可以知道,原因就是因为 ListView 的 onItemLongClickListener 的 onItemLongClick 方法返回 true,最终导致调用 View 的 performLongClick 返回为 true 的,调用 Editor 的 performLongClick 就什么都没做,也就不会显示复制、粘贴的上下文菜单了。
- 解决方法
在 onItemLongClick 方法进行判断有没有是不是长按 Edittext太麻烦了,我选择的方法时:重载 Edittext 的 showContextMenu 方法,默认返回为 false
经过检验,这个方法是可行的。
小结
如果本来就是需要 Edittext 长按不弹出上下文菜单,有下面几种方法:
Edittext 设置 onLongClickListener,返回 true
重载 Edittext 的 showContextMenu 方法,默认返回为 true