Android的menu有多种实现方式,Action Mode是Android 3.0以后出现的,我们可以使用AppCompat库使Action Mode兼容至Android 2.1。
Android 3.0以前,我们处理列表的长按事件经常使用Context Menu,Android3.0以后,我们有了新的选择:Action Mode。下图左边效果为Context Menu右边效果为Action Mode。
Android开发者应该都熟悉Context Menu了,Context Menu是悬浮在操作项之上的视图。Action Mode是临时占据了ActionBar的位置。
关于Action Mode 详细资料:http://developer.android.com/guide/topics/ui/menus.html#context-menu
自己写了一个示例以增强记忆运行效果如下:
在TextView上使用Contextual Action Mode
在ListView上使用Contextual Action Mode
1、在单个View上使用Contextual Action Mode
package com.example.cabtest; import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnLongClickListener; import android.widget.TextView; import android.widget.Toast; public class IndividualviewsCAMActivity extends Activity { private ActionMode mActionMode; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_individual); super.onCreate(savedInstanceState); ActionBar mActionBar = getActionBar(); mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setDisplayUseLogoEnabled(true); findView(); } @SuppressLint("NewApi") private void findView() { String content = "北京时间12月5日消息,据国外科技网站BusinessInsider报道,日前,美国麻省理工学院(MIT)有形媒体小组的一个研究团队研发出了一种新的人机交互技术——人类可以进入电脑进行远程的物理操作。该技术现在只能模拟非常基本的动作,比如击掌或是来回拍球。而在未来,一个更复杂的版本或许能够在更大的屏幕上工作,并重现整个人体。"; TextView tv_content = (TextView) findViewById(R.id.tv_content); tv_content.setText(content); tv_content.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { if (mActionMode != null) { return false; } mActionMode = IndividualviewsCAMActivity.this .startActionMode(mActionModeCallback); v.setSelected(true); return true; } }); } @SuppressLint("NewApi") private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu_individual, 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_copy: Toast.makeText(getApplicationContext(), R.string.menu_copy, Toast.LENGTH_SHORT).show(); mode.finish(); // Action picked, so close the CAB return true; case R.id.menu_delete: Toast.makeText(getApplicationContext(), R.string.menu_delete, Toast.LENGTH_SHORT).show(); mode.finish(); // Action picked, so close the CAB return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.context_menu_test, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: // app icon in action bar clicked; go home Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; default: return super.onOptionsItemSelected(item); } } }
context_menu_individual.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_copy" android:icon="@drawable/ic_copy" android:orderInCategory="1" android:showAsAction="always" android:title="@string/menu_copy"/> <item android:id="@+id/menu_delete" android:icon="@drawable/ic_delete" android:orderInCategory="2" android:showAsAction="always" android:title="@string/menu_delete"/> </menu>
2、在ListView/GridView 上使用Contextual Action Mode
package com.example.cabtest; import java.util.ArrayList; import java.util.List; import com.example.cabtest.entity.Book; import android.app.ActionBar; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class ListCAMActivity extends Activity { private List<Book> mList = new ArrayList<Book>(); private List<Book> checkedList = new ArrayList<Book>(); private BookAdapter mAdapter; private ListView mListView; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_list); super.onCreate(savedInstanceState); ActionBar mActionBar = getActionBar(); mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setDisplayUseLogoEnabled(true); initData(); findView(); } private void initData() { for (int i = 0; i < 40; i++) { Book book = new Book(); book.setId(i); book.setName("Thinking In Java " + i); mList.add(book); } } private void findView() { mListView = (ListView) findViewById(R.id.mListView); mAdapter = new BookAdapter(); mListView.setAdapter(mAdapter); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { // Here you can do something when items are // selected/de-selected,such as update the title in the CAB Book book = mList.get(position); if (checked) { book.setChecked(true); checkedList.add(book); } else { checkedList.remove(book); book.setChecked(false); } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } setSubtitle(mode); } private void setSubtitle(ActionMode mode) { int checkedCount = checkedList.size(); // int checkedCount = mListView.getCheckedItemCount(); switch (checkedCount) { case 0: mode.setSubtitle(null); break; default: mode.setSubtitle("选择了" + checkedCount + "项"); break; } } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // Respond to clicks on the actions in the CAB switch (item.getItemId()) { case R.id.menu_delete: mList.removeAll(checkedList); if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } Toast.makeText(getApplicationContext(), R.string.menu_delete, Toast.LENGTH_SHORT).show(); checkedList.clear(); mode.finish(); // Action picked, so close the CAB return true; case R.id.menu_edit: Toast.makeText(getApplicationContext(), R.string.menu_edit, Toast.LENGTH_SHORT).show(); mode.finish(); // Action picked, so close the CAB return true; case R.id.menu_detail: Toast.makeText(getApplicationContext(), R.string.menu_detail, Toast.LENGTH_SHORT).show(); mode.finish(); // Action picked, so close the CAB return true; default: return false; } } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate the menu for the CAB MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu_list, menu); return true; } @Override public void onDestroyActionMode(ActionMode mode) { // Here you can make any necessary updates to the activity when // the CAB is removed. By default, selected items are // deselected/unchecked. } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // Here you can perform updates to the CAB due to // an invalidate() request return false; } }); } private class BookAdapter extends BaseAdapter { @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = View.inflate(getApplicationContext(), R.layout.list_item, null); holder = new ViewHolder(); holder.tv_name = (TextView) convertView .findViewById(R.id.tv_name); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Book book = mList.get(position); if(book.isChecked()){ convertView.setBackgroundColor(getResources().getColor(R.color.blur)); }else{ convertView.setBackgroundColor(getResources().getColor(R.color.white)); } holder.tv_name.setText(book.getName()); return convertView; } } static class ViewHolder { TextView tv_name; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.context_menu_test, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: // app icon in action bar clicked; go home Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; default: return super.onOptionsItemSelected(item); } } }
context_menu_list.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_delete" android:icon="@drawable/ic_delete" android:orderInCategory="1" android:showAsAction="always" android:title="@string/menu_delete"/> <item android:id="@+id/menu_edit" android:icon="@drawable/ic_edit" android:orderInCategory="2" android:showAsAction="always" android:title="@string/menu_edit"/> <item android:id="@+id/menu_detail" android:icon="@drawable/ic_detail" android:orderInCategory="3" android:showAsAction="always" android:title="@string/menu_detail"/> </menu>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:textColor="@color/black"/> </LinearLayout>
context_menu_test.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_refresh" android:icon="@drawable/ic_action_refresh" android:orderInCategory="1" android:showAsAction="always" android:title="@string/menu_refresh"/> <item android:id="@+id/menu_search" android:icon="@drawable/ic_action_search" android:orderInCategory="2" android:showAsAction="always" android:title="@string/menu_search"/> </menu>
Demo下载地址:http://download.csdn.net/detail/fx_sky/6663421