从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