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)


原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/3176.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论