android的上下文菜单和上下文操作模式

本文介绍如何在Android应用中实现上下文菜单功能,包括创建菜单资源文件、注册视图、处理菜单选择事件以及实现多选操作等内容。

例如长按删除功能就是一种上下文操作,上下文操作与某个特定的屏幕视图(单个列表项)而非整个屏幕相关联

一:在res/menu下新建菜单资源文件

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menu_item_delete_crime"
        android:icon="@android:drawable/ic_menu_delete"
        android:title="@string/delete_crime"
        ></item>

</menu>


二:创建上下文菜单和响应

onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)创建

onContextItemSelected(MenuItem item)响应

创建上下文菜单:

        @Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu);
		
	}
默认情况下,长按视图不会触发上下文菜单的创建,要触发上下文菜单的创建,就要在onCreateView中调用Fragment的registerForContextMenu(View view)登记一个视图

ListView listView = (ListView) v.findViewById(android.R.id.list);
registerForContextMenu(listView);


响应上下文菜单选择

调用onContextItemSelected(MenuItem item),并在方法中编写响应逻辑,例如我要进行删除

        @Override
	public boolean onContextItemSelected(MenuItem item){
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
	    int position = info.position;
	    CrimeAdapter adapter = (CrimeAdapter) getListAdapter();
	    Crime crime = adapter.getItem(position);
	    
	    switch (item.getItemId()) {
		case R.id.menu_item_delete_crime:
			CrimeLab.get(getActivity()).delete(crime);
			adapter.notifyDataSetChanged();
			return true;
		default:
			break;
		}
	    
		return super.onContextItemSelected(item);
	}

三:如果要实现列表视图的多选操作(例如长按可以选多多个item删除)

1.在onCreateView中设置列表视图的选择模式为CHOICE_MODE_MULTIPLE_MODAL

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
此时已经实现了列表视图的多选模式了

2.列表视图的操作模式回调方法

                                listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
				
				@Override
				public void onItemCheckedStateChanged(ActionMode mode, int position,
						long id, boolean checked) {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public boolean onCreateActionMode(ActionMode mode, Menu menu) {
					// TODO Auto-generated method stub
					MenuInflater inflater = mode.getMenuInflater();
					inflater.inflate(R.menu.crime_list_item_context, menu);
					return true;
				}
				
				@Override
				public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
					// TODO Auto-generated method stub
					return false;
				}
				
				@Override
				public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
					switch (item.getItemId()) {
					case R.id.menu_item_delete_crime:
						CrimeAdapter adapter = (CrimeAdapter) getListAdapter();
						CrimeLab crimeLab = CrimeLab.get(getActivity());
						for(int i = adapter.getCount() - 1; i >= 0; i--){
							if(getListView().isItemChecked(i)){
								crimeLab.delete(adapter.getItem(i));
							}
						}
						mode.finish();
						adapter.notifyDataSetChanged();
						return true;

					default:
						return false;
					}
				}
				
				@Override
				public void onDestroyActionMode(ActionMode mode) {
					// TODO Auto-generated method stub
					
				}
	
			});

为视图实现AbsListView.MultiChoiceModeListener接口的监听器,该接口包含onItemCheckedStateChanged(Action mode, int position, long id, boolean checked)这个方法,每当视图被选中或者撤销的都会触发此方法,但由于AbsListView.MultiChoiceModeListener接口包含了ActionMode.callback接口,所以还要实现一下几个方法:

1.public abstract boolean onCreateActionMode(ActionMode mode, Menu menu)

在ActionMode对象创建后使用,实例化菜单并显示在上下文操作栏的地方

2.public boolean onPrepareActionMode(ActionMode mode, Menu menu)

上下文需要刷新显示新数据时调用

3.public boolean onActionItemClicked(ActionMode mode, MenuItem item)

用户选中某个菜单项操作时调用,响应上下文菜单操作的地方

4.public void onDestroyActionMode(ActionMode mode)

一般在actionmode销毁时选用


四:此时可以实现多选操作了,但是长按已选背景并没有改变,导致用户不能区分

首先,在res/drawable目录下新建background_activated.xml文件

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item 
        android:state_activated="true"
        android:drawable="@android:color/darker_gray">
        
    </item>

</selector>

state_activated为true,表明当引用该资源的视图(此处为listview)处于激活状态时,则使用android:drawable属性所指定的资源。

如果为false,则只要视图处于未被激活时,android:drawable属性所指定的资源都会被使用

然后在原来视图(此处为listview)加上属性android:background="@drawable/background_activated"

此时长按列表项,被选中的listItem就会显示darker_gray的颜色


思考:

以上所说的上下文操作栏可以完美得应用于ListView和GirdView,但是对于其它视图,是不支持的。

对于其他视图,我们首先设置一个实现View.OnLongClickListener接口的监听器,然后在监听器体内,调用Activity的startActionMode()创建一个actionMode实例,MultiChoiceModeListener接口中的ActionMode实例是自动创建的,startActionMode()需要一个实现ActionMode.callBack接口对象作为参数,因此创建一个ActionMode.callBack接口的实现,自然也要实现那四个方法:

1.public abstract boolean onCreateActionMode(ActionMode mode, Menu menu)

2.public boolean onPrepareActionMode(ActionMode mode, Menu menu)

3.public boolean onActionItemClicked(ActionMode mode, MenuItem item)

4.public void onDestroyActionMode(ActionMode mode)







评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值