从mediaTek项目中移植出来的,完整的代码可以在我的GitHub上看到,下面看一下效果:
主Activity:
package com.zms.todo; import java.util.Locale; import android.app.ActionBar; import android.app.ActionBar.LayoutParams; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.ActionMode; import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; import android.widget.PopupMenu; import android.widget.TextView; import android.widget.PopupMenu.OnMenuItemClickListener; public class TodoActivity extends Activity { private static final String TAG = "TodosActivity"; private static final int REQUEST_ADD_NEW = 1; private static final int REQUEST_SHOW_DETAILS = REQUEST_ADD_NEW + 1; private static final int DIALOG_DELETE_ITEMS = 1; private boolean mShowingDialog = false; private TimeChangeReceiver mTimeChangeReceiver = null; /** * display number of All Todos */ private TextView mNumberTextView; private MenuItem mBtnChangeState; private MenuItem mBtnDelete; /** * Read all Todo infos from QB */ private TodoListAdapter mTodoListAdapter = null; /** * Show all Todo infos in ListView */ private ListView mTodosListView = null; /** * Item click & long click listener */ private AdapterViewListener mAdapterViewListener = null; /** * Action Mode */ private ActionMode mActionMode = null; private TodosActionModeCallBack mTodosActionCallBack = new TodosActionModeCallBack(); /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.items); initViews(); configureActionBar(); mTimeChangeReceiver = TimeChangeReceiver.registTimeChangeReceiver(this); mTimeChangeReceiver.addDateChangeListener(mTodoListAdapter); LogUtils.d(TAG, "TodosActivity.onCreate() finished."); } private void initViews() { mTodoListAdapter = new TodoListAdapter(this); mAdapterViewListener = new AdapterViewListener(); mTodosListView = (ListView) findViewById(R.id.list_todos); mTodosListView.setAdapter(mTodoListAdapter); mTodosListView.setOnItemClickListener(mAdapterViewListener); mTodosListView.setOnItemLongClickListener(mAdapterViewListener); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { LogUtils.d(TAG, "onActivityResult request=" + requestCode + " result=" + resultCode); TodoInfo info = null; switch (resultCode) { case Utils.OPERATOR_INSERT: info = (TodoInfo) data.getSerializableExtra(Utils.KEY_PASSED_DATA); mTodoListAdapter.addItem(info); final int addPos = mTodoListAdapter.getItemPosition(info); mTodosListView.setSelection(addPos); break; case Utils.OPERATOR_UPDATE: info = (TodoInfo) data.getSerializableExtra(Utils.KEY_PASSED_DATA); if (null == info) { LogUtils.e(TAG, "result: OPERATOR_UPDATE, but data didn't contain the info"); return; } mTodoListAdapter.updateItemData(info); final int updatePos = mTodoListAdapter.getItemPosition(info); mTodosListView.setSelection(updatePos); break; case Utils.OPERATOR_DELETE: info = (TodoInfo) data.getSerializableExtra(Utils.KEY_PASSED_DATA); if (null == info) { LogUtils.e(TAG, "result: OPERATOR_DELETE, but data didn't contain the info"); return; } mTodoListAdapter.removeItem(info); break; default: break; } } @Override protected void onResume() { super.onResume(); if (mShowingDialog) { showDialog(DIALOG_DELETE_ITEMS); } } @Override protected void onPause() { if (mShowingDialog) { removeDialog(DIALOG_DELETE_ITEMS); } super.onPause(); } @Override protected void onDestroy() { mTimeChangeReceiver.clearChangeListener(); unregisterReceiver(mTimeChangeReceiver); super.onDestroy(); } @Override public void onBackPressed() { if (mTodoListAdapter.isEditing()) { updateToEditNull(); return; } super.onBackPressed(); } private void updateToEditNull() { if (mActionMode != null) { mActionMode.finish(); } invalidateOptionsMenu(); mTodoListAdapter.setEditingType(TodoListAdapter.EDIT_NULL); } @Override protected Dialog onCreateDialog(int id) { AlertDialog dialog = null; switch (id) { case DIALOG_DELETE_ITEMS: dialog = new AlertDialog.Builder(this).setTitle(R.string.delete) .setMessage(R.string.delete_selected_items) .setIconAttribute(android.R.attr.alertDialogIcon).create(); dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getText(R.string.cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mShowingDialog = false; } }); dialog.setButton(DialogInterface.BUTTON_POSITIVE, getText(R.string.delete), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mTodoListAdapter.deleteSelectedItems(); updateToEditNull(); updateBottomBarWidgetState(); mShowingDialog = false; } }); dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { public void onCancel(DialogInterface dialog) { mShowingDialog = false; } }); return dialog; default: break; } return super.onCreateDialog(id); } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DIALOG_DELETE_ITEMS: String msg = ""; if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_TODOS) { if (mTodoListAdapter.getSeletedTodosNumber() > 1) { msg = getString(R.string.delete_selected_items); } else { msg = getString(R.string.delete_item); } ((AlertDialog) dialog).setMessage(msg); } else if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_DONES) { if (mTodoListAdapter.getSeletedDonesNumber() > 1) { msg = getString(R.string.delete_selected_items); } else { msg = getString(R.string.delete_item); } ((AlertDialog) dialog).setMessage(msg); } break; default: break; } } void updateBottomBarWidgetState() { LogUtils.d(TAG, "updateBottomBarWidgetState(), editing=" + mTodoListAdapter.isEditing()); if (mTodoListAdapter.isEditing()) { int selectedNumber = 0; int dataSourceNumber = 0; if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_TODOS) { selectedNumber = mTodoListAdapter.getSeletedTodosNumber(); dataSourceNumber = mTodoListAdapter.getTodosDataSource().size(); } else if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_DONES) { selectedNumber = mTodoListAdapter.getSeletedDonesNumber(); dataSourceNumber = mTodoListAdapter.getDonesDataSource().size(); } LogUtils.d(TAG, "selectedNumber=" + selectedNumber + ", dataSourceNumber=" + dataSourceNumber); if (dataSourceNumber == 0) { updateToEditNull(); } else { ///M: add to avoid this case: no item has been selected but the button // can be pressed {@ if (selectedNumber > 0) { mBtnDelete.setEnabled(true); mBtnChangeState.setEnabled(true); } else { mBtnDelete.setEnabled(false); mBtnChangeState.setEnabled(false); } /// @} mTodosActionCallBack.updateActionMode(); } } } private void onChangeItemStateClick() { String currentStatus = null; String targetStatus = null; if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_TODOS) { currentStatus = TodoInfo.STATUS_TODO; targetStatus = TodoInfo.STATUS_DONE; } else if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_DONES) { currentStatus = TodoInfo.STATUS_DONE; targetStatus = TodoInfo.STATUS_TODO; } mTodoListAdapter.updateSelectedStatus(currentStatus, targetStatus); updateToEditNull(); } class AdapterViewListener implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) { int viewType = mTodoListAdapter.getItemViewType(position); LogUtils.d(TAG, "onItemClick viewType =" + viewType + " position=" + position); boolean selectDoneItem = false; switch (viewType) { case TodoListAdapter.TYPE_TODOS_HEADER: mTodoListAdapter.setTodosExpand(!mTodoListAdapter.isTodosExpand()); break; case TodoListAdapter.TYPE_TODOS_FOOTER: if (!mTodoListAdapter.isEditing()) { Intent intentAdd = new Intent(TodoActivity.this, EditTodoActivity.class); startActivityForResult(intentAdd, REQUEST_ADD_NEW); } break; case TodoListAdapter.TYPE_DONES_HEADER: mTodoListAdapter.setDonesExpand(!mTodoListAdapter.isDonesExPand()); break; case TodoListAdapter.TYPE_DONES_ITEM: selectDoneItem = true; case TodoListAdapter.TYPE_TODOS_ITEM: if (mTodoListAdapter.isEditing()) { if (mTodoListAdapter.getSelectedNum() == 0) { // its status is re-select, switch the type. int editType = selectDoneItem ? TodoListAdapter.EDIT_DONES : TodoListAdapter.EDIT_TODOS; mTodoListAdapter.setEditingType(editType); //update change state icon updateChangeStateIcon(editType); } final boolean todosEditAble = viewType == TodoListAdapter.TYPE_TODOS_ITEM && mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_TODOS; final boolean donesEditAble = viewType == TodoListAdapter.TYPE_DONES_ITEM && mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_DONES; if (todosEditAble || donesEditAble) { Object tag = view.getTag(); if (tag != null && tag instanceof TodoListAdapter.ViewHolder) { TodoListAdapter.ViewHolder holder = (TodoListAdapter.ViewHolder) tag; final boolean checked = holder.mTodoInfoCheckBox.isChecked(); holder.mTodoInfoCheckBox.setChecked(!checked); mTodoListAdapter.selectItem(position, !checked); } } updateBottomBarWidgetState(); updateActionModeTitle(); } else { Intent intentDetails = new Intent(TodoActivity.this, EditTodoActivity.class); TodoInfo info = (TodoInfo) adapterView.getAdapter().getItem(position); intentDetails.putExtra(Utils.KEY_PASSED_DATA, info); startActivityForResult(intentDetails, REQUEST_SHOW_DETAILS); } break; default: break; } } public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long rowId) { final int viewType = mTodoListAdapter.getItemViewType(position); int editType = TodoListAdapter.EDIT_NULL; switch (viewType) { case TodoListAdapter.TYPE_TODOS_ITEM: editType = TodoListAdapter.EDIT_TODOS; break; case TodoListAdapter.TYPE_DONES_ITEM: editType = TodoListAdapter.EDIT_DONES; break; default: LogUtils.d(TAG, "cann't switch viewType:" + viewType); } LogUtils.d(TAG, "onItemLongClick viewType =" + viewType + " position=" + position + " editType=" + editType); if (mTodoListAdapter.isEditing() && editType != mTodoListAdapter.getEditType() && getSelectedCount() != 0) { // In multi-select mode, not allow do the long click when item // is not in edit mode. return true; } if (editType != TodoListAdapter.EDIT_NULL && editType != mTodoListAdapter.getEditType()) { if (mTodoListAdapter.setEditingType(editType)) { // when first long click,start action mode startTodoActionMode(); } updateChangeStateIcon(editType); } if (editType != TodoListAdapter.EDIT_NULL) { Object tag = view.getTag(); if (tag != null && tag instanceof TodoListAdapter.ViewHolder) { TodoListAdapter.ViewHolder holder = (TodoListAdapter.ViewHolder) tag; final boolean checked = holder.mTodoInfoCheckBox.isChecked(); holder.mTodoInfoCheckBox.setChecked(!checked); mTodoListAdapter.selectItem(position, !checked); } } updateActionModeTitle(); updateBottomBarWidgetState(); return true; } } @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); switch (item.getItemId()) { case R.id.btn_new_todo: Intent intent = new Intent(TodoActivity.this, EditTodoActivity.class); startActivityForResult(intent, REQUEST_ADD_NEW); break; default: break; } return true; } public void updateHeaderNumberText(String text) { mNumberTextView.setText(text); } /** * configure the action bar */ private void configureActionBar() { ActionBar actionBar = getActionBar(); actionBar.setDisplayShowHomeEnabled(true); actionBar.setDisplayShowCustomEnabled(true); View actionBarNumberView = getLayoutInflater().inflate(R.layout.title_bar_number, null); actionBar.setCustomView(actionBarNumberView, new LayoutParams(Gravity.END)); mNumberTextView = (TextView) actionBarNumberView.findViewById(R.id.number); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.list_default, menu); return true; } class TodosActionModeCallBack implements ActionMode.Callback { private Button mSelectionButton; private PopupMenu mSelectionMenu; @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mActionMode = mode; getMenuInflater().inflate(R.menu.list_edit, menu); mBtnChangeState = menu.findItem(R.id.btn_change_state); mBtnDelete = menu.findItem(R.id.btn_delete); startSelectionMode(mActionMode); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { updateActionModeTitle(); return true; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_select_all: if (mTodoListAdapter.isSelectedAll()) { mTodoListAdapter.allSelectAction(false); } else { mTodoListAdapter.allSelectAction(true); } updateBottomBarWidgetState(); break; case R.id.btn_change_state: onChangeItemStateClick(); updateBottomBarWidgetState(); break; case R.id.btn_delete: showDialog(DIALOG_DELETE_ITEMS); mShowingDialog = true; break; default: } updateActionModeTitle(); return true; } @Override public void onDestroyActionMode(ActionMode mode) { //close mode action & exit editing mode mActionMode = null; onBackPressed(); } private void startSelectionMode(final ActionMode actionMode) { View customView = getLayoutInflater().inflate(R.layout.action_mode, null); actionMode.setCustomView(customView); mSelectionButton = (Button) customView.findViewById(R.id.selection_menu); mSelectionMenu = new PopupMenu(TodoActivity.this, mSelectionButton); mSelectionMenu.getMenuInflater().inflate(R.menu.selection, mSelectionMenu.getMenu()); mSelectionMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { return onActionItemClicked(actionMode, item); } }); mSelectionButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { updateSelectPopupMenu(); mSelectionMenu.show(); } }); } private void updateSelectPopupMenu() { MenuItem item = mSelectionMenu.getMenu().findItem(R.id.action_select_all); if (item != null) { if (mTodoListAdapter.isSelectedAll()) { item.setChecked(true); item.setTitle(R.string.unselect_all); } else { item.setChecked(false); item.setTitle(R.string.select_all); } } } public void updateActionMode() { int num = getSelectedCount(); String str = getResources().getString(R.string.selected_count); str = String.format(Locale.US, str, num); mSelectionButton.setText(str); updateSelectPopupMenu(); if (mActionMode != null) { mActionMode.invalidate(); } } } private int getSelectedCount() { int num = -1; if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_TODOS) { num = mTodoListAdapter.getSeletedTodosNumber(); } else if (mTodoListAdapter.getEditType() == TodoListAdapter.EDIT_DONES) { num = mTodoListAdapter.getSeletedDonesNumber(); } else { LogUtils.w(TAG, "mTodosListAdapter.getEditType():+mTodosListAdapter.getEditType()" + ",may be has error."); } return num; } private void updateActionModeTitle() { if (mActionMode != null) { int num = getSelectedCount(); String str = getResources().getString(R.string.selected_count); str = String.format(str, num); mActionMode.setTitle(str); } } private void startTodoActionMode() { if (mActionMode == null) { mActionMode = startActionMode(mTodosActionCallBack); } } private void updateChangeStateIcon(int editType) { if (editType == TodoListAdapter.EDIT_TODOS) { // mark done if in to-do state mBtnChangeState.setIcon(R.drawable.todo_mark_done); mBtnChangeState.setTitle(R.string.mark_todo);// "Mark as Done" } else if (editType == TodoListAdapter.EDIT_DONES) { // mark to do if in done state mBtnChangeState.setIcon(R.drawable.todo_mark_todo); mBtnChangeState.setTitle(R.string.mark_done);// "Mark as ToDo" } } }
转载请注明出处:周木水的CSDN博客 http://blog.csdn.net/zhoumushui
我的GitHub:周木水的GitHub https://github.com/zhoumushui
原文地址:http://blog.csdn.net/zhoumushui/article/details/43730293