OnCreateContextMenuListener,MultiChoiceModeListener和OnLongClickListener的优先级
来源:互联网 发布:中世纪2优化9 圣殿骑士 编辑:程序博客网 时间:2024/06/05 04:39
查看短信源码的时候,对于以下代码,发现一个问题:
listView.setOnCreateContextMenuListener(mConvListOnCreateContextMenuListener); listView.setOnKeyListener(mThreadListKeyListener); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); listView.setMultiChoiceModeListener(new ModeCallback()); private class ModeCallback implements ListView.MultiChoiceModeListener { private View mMultiSelectActionBarView; private TextView mSelectedConvCount; private HashSet<Long> mSelectedThreadIds; @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { } @Override public void onDestroyActionMode(ActionMode mode) { } @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { } } private final OnCreateContextMenuListener mConvListOnCreateContextMenuListener = new OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { } }; @Override public boolean onContextItemSelected(MenuItem item) { }
OnCreateContextMenuListener,MultiChoiceModeListener和OnLongClickListener(这里没有出现)都是长按view然后回调,那么有什么区别呢?查看源码(View.java
):
public boolean performLongClick() { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); boolean handled = false; ListenerInfo li = mListenerInfo; if (li != null && li.mOnLongClickListener != null) { handled = li.mOnLongClickListener.onLongClick(View.this); } if (!handled) { handled = showContextMenu(); } if (handled) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); } return handled; }
可以发现,对于普通的View,优先响应OnLongClickListener,如果没有处理然后才是交给ContextMenuListener处理。而MultiChoiceModeListener是
AbsListView定义的,所以可以从AbsListView中寻找答案。
“`
public void setMultiChoiceModeListener(MultiChoiceModeListener listener) {
if (mMultiChoiceModeCallback == null) {
mMultiChoiceModeCallback = new MultiChoiceModeWrapper();
}
mMultiChoiceModeCallback.setWrapped(listener);
}
boolean performLongPress(final View child, final int longPressPosition, final long longPressId) { // CHOICE_MODE_MULTIPLE_MODAL takes over long press. if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) { if (mChoiceActionMode == null && (mChoiceActionMode = startActionMode(mMultiChoiceModeCallback)) != null) { setItemChecked(longPressPosition, true); performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); } return true; } boolean handled = false; if (mOnItemLongClickListener != null) { handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, child, longPressPosition, longPressId); } if (!handled) { mContextMenuInfo = createContextMenuInfo(child, longPressPosition, longPressId); handled = super.showContextMenuForChild(AbsListView.this); } if (handled) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); } return handled;}@Overridepublic boolean showContextMenuForChild(View originalView) { final int longPressPosition = getPositionForView(originalView); if (longPressPosition >= 0) { // 注意!见后文 final long longPressId = mAdapter.getItemId(longPressPosition); boolean handled = false; if (mOnItemLongClickListener != null) { handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, originalView, longPressPosition, longPressId); } if (!handled) { mContextMenuInfo = createContextMenuInfo( getChildAt(longPressPosition - mFirstPosition), longPressPosition, longPressId); handled = super.showContextMenuForChild(originalView); } return handled; } return false;}
AbsListView重写了onTouchEvent。可以发现,处理长按事件的优先级为:MultiChoiceModeCallback > ItemLongClickListener > ContextMenuListener注意,如果ListView的Adapter是CursorAdapter的话,那么上面showContextMenuForChild调用了adapter的getItemId,这样cursor已经移动了!!
public long getItemId(int position) { if (mDataValid && mCursor != null) { if (mCursor.moveToPosition(position)) { return mCursor.getLong(mRowIDColumn); } else { return 0; } } else { return 0; }}
##关于ContextMenu大意是AdapterVIew在onContextItemSelected中可以确定是AdapterView调出的ContextMenu,因为
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); long id = menuInfo.id;//这个id是showContextMenuForChild中item的id
…
}
AdapterView.java包含:
@Override
protected ContextMenuInfo getContextMenuInfo() {
return mContextMenuInfo;
}
而普通的view没有,所以需要自定view(以ImageView为例子):
public class ImageViewWithContextMenuInfo extends ImageView {
public ImageViewWithContextMenuInfo(Context context) {
super(context);
}
@Override protected ContextMenuInfo getContextMenuInfo() { return new ImageViewContextMenuInfo(this); } public ImageViewWithContextMenuInfo(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ImageViewWithContextMenuInfo(Context context, AttributeSet attrs) { super(context, attrs); } public static class ImageViewContextMenuInfo implements ContextMenu.ContextMenuInfo { public ImageViewContextMenuInfo(View targetView) { this.targetView = (ImageView) targetView; } public ImageView targetView; }
}
用法:
public boolean onContextItemSelected(MenuItem item) {
ImageViewWithContextMenuInfo.ImageViewContextMenuInfo menuInfo = (ImageViewWithContextMenuInfo.ImageViewContextMenuInfo) item.getMenuInfo();
ImageViewWithContextMenuInfo img = (ImageViewWithContextMenuInfo) menuInfo.targetView;
“`
来源:
http://ogrelab.ikratko.com/identifying-the-view-selected-in-a-contextmenu-in-oncontextitemselected-method/
- OnCreateContextMenuListener,MultiChoiceModeListener和OnLongClickListener的优先级
- 浅谈OnTouchListener,OnClickListener和OnLongClickListener的关系
- View.OnCreateContextMenuListener的调用顺序
- &&和||的优先级
- *和++的优先级?
- STM32的抢占优先级和响应优先级
- 抢占优先级和相应优先级以及优先级分组的理解
- IP优先级、TOS优先级、DSCP优先级和802.1p优先级的区别
- Android之MultiChoiceModeListener简析
- OnTouch三种OnClickListener、OnTouchListener、OnLongClickListener的学习
- android应用中常用的监听OnTouchListener、OnClickListener、OnLongClickListener
- 长按OnLongClickListener无法修改长按时间的解决办法
- onTouchListener和onTouch的优先级
- JAVA && 和 || 优先级的问题
- *p++的优先级和使用
- onLongClickListener使用
- 中断响应优先级和中断处理优先级的区别
- STM32F4中断抢占优先级和响应优先级的概念
- java BigDecimal 高精度运算 小数点处理详解
- thinkphp自定义模板标签(二)
- iOS UI基础学习历程
- pyqt5载入qml
- spring bean scope 单例与多例
- OnCreateContextMenuListener,MultiChoiceModeListener和OnLongClickListener的优先级
- freemarker模板解析过程
- MySQL 调优/优化的 100 个建议
- JUnit快速入门
- freemarker数据类型
- 算法_10 : 图算法_5: 图的染色
- NYOJ-6-喷水装置(一)
- 关于ImageView的源码简单解析
- Shiro学习--Apache Shiro Tutorial 环境搭建