轉載請註明出處:http://blog.csdn.net/zhaokaiqiang1992
ActionMode是3.0之後,官方推薦的一種上下文菜單的實現方式,在之前一直用的是Context Menu,今天這篇文章簡單介紹一下ActionMode,並實現多選刪除功能。
如果要在ListView這類控件中實現多選,我們可以通過設置setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL)來實現,然後通過設置setMultiChoiceModeListener之後,就可以開啓ActionMode。ActionMode並不是一個View,只是一個操作模式,所以我們用的時候不能按照View的用法來使用。
下面是實現的效果圖
這個和GMail的刪除是不是很像?
因爲ActionMode沒有多少知識點要說,咱們就簡單介紹下,然後上代碼,這個功能主要其實主要是邏輯麻煩點,也很簡單。
設置完多選模式監聽器之後,我們需要實現下面的方法
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener(){
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
}
@Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
// TODO Auto-generated method stub
}
});
就5個方法,看名字也很好理解。
在onCreateActionMode()中,一般實現ActionMode下右側的MenuItem配置,和標題設置,比如像下面這樣
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 在進入ActionMode的時候調用
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_delete, menu);
mode.setTitle("Delete");
isInActionMode = true;
isInDeleteMode = false;
return true;
}
onActionItemClicked則是在我們設置的MenuItem點擊之後調用,和ActionBar裏面的MenuItem一樣,所以我們可以像下面這樣
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// 當listview中的item被點擊的時候調用
if (item.getItemId() == R.id.action_delete) {
mAnimateDismissAdapter.animateDismiss(mCheckedPositions);
isInDeleteMode = true;
mode.finish();
return true;
}
return false;
}
onItemCheckedStateChanged則是我們的listview的item點擊的時候調用,我們可以根據position和checked進行邏輯操作。
基本這幾個方法就基本滿足我們的功能了,下面是完整的示例代碼
package com.imooc.multychoice;
import java.util.ArrayList;
import java.util.Iterator;
import android.app.Activity;
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;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import com.haarman.listviewanimations.itemmanipulation.AnimateDismissAdapter;
import com.haarman.listviewanimations.itemmanipulation.OnDismissCallback;
import com.imooc.multychoice.R;
public class MainActivity extends Activity {
protected static final String TAG = "TAG";
private ListView mListView;
private MultyAdapter mAdapter;
// 是否處於ActionMode模式
private boolean isInActionMode;
private boolean isInDeleteMode = false;
private AnimateDismissAdapter<Model> mAnimateDismissAdapter;
private ArrayList<Integer> mCheckedPositions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.lv);
mAdapter = new MultyAdapter();
mCheckedPositions = new ArrayList<Integer>();
mAnimateDismissAdapter = new AnimateDismissAdapter<MainActivity.Model>(
mAdapter, new MyDismissCallBack());
mAnimateDismissAdapter.setAbsListView(mListView);
mListView.setAdapter(mAnimateDismissAdapter);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// 在退出ActionMode的時候調用,如果處於刪除狀態,就刪除選中的數據,
// 否則,重置所有選中的狀態
if (!isInDeleteMode) {
for (Model model : mAdapter.models) {
model.setChecked(false);
}
mCheckedPositions.clear();
}
isInActionMode = false;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 在進入ActionMode的時候調用
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_delete, menu);
mode.setTitle("Delete");
isInActionMode = true;
isInDeleteMode = false;
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// 當listview中的item被點擊的時候調用
if (item.getItemId() == R.id.action_delete) {
mAnimateDismissAdapter.animateDismiss(mCheckedPositions);
isInDeleteMode = true;
mode.finish();
return true;
}
return false;
}
@Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
// 當item的選中狀態被選中的時候調用
mAdapter.models.get(position).setChecked(checked);
mAdapter.notifyDataSetChanged();
mode.setSubtitle(mListView.getCheckedItemCount()
+ " item selected");
if (mCheckedPositions.contains(position) && !checked) {
mCheckedPositions.remove(Integer.valueOf(position));
} else {
mCheckedPositions.add(position);
}
}
});
}
private class MultyAdapter extends BaseAdapter {
private ArrayList<Model> models;
public MultyAdapter() {
models = new ArrayList<Model>();
for (int i = 0; i < 20; i++) {
models.add(new Model("I'm " + i));
}
}
@Override
public int getCount() {
return models.size();
}
@Override
public Model getItem(int position) {
return models.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
Model model = mAdapter.models.get(position);
if (convertView == null) {
convertView = getLayoutInflater().inflate(
R.layout.item_multy_choice, parent, false);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) convertView.findViewById(R.id.tv);
viewHolder.chb = (CheckBox) convertView.findViewById(R.id.chb);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setText(model.getTitle());
viewHolder.chb.setChecked(model.isChecked());
viewHolder.chb.setVisibility(isInActionMode ? View.VISIBLE
: View.GONE);
return convertView;
}
}
private static class ViewHolder {
TextView tv;
CheckBox chb;
}
/**
* 測試Model
*
* @author zhaokaiqiang
*
*/
private class Model {
private String title;
private boolean isChecked;
public Model(String title) {
this.title = title;
isChecked = false;
}
public String getTitle() {
return title;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
}
}
private class MyDismissCallBack implements OnDismissCallback {
@Override
public void onDismiss(AbsListView arg0, int[] arg1) {
mCheckedPositions.clear();
Iterator<Model> iterator = mAdapter.models.iterator();
while (iterator.hasNext()) {
if (iterator.next().isChecked()) {
// 刪除選中的元素
iterator.remove();
}
}
mAdapter.notifyDataSetChanged();
}
}
}
在上面的代碼中,爲了實現動畫效果,我使用了開源項目ListViewAnimation中的AnimationDismissAdapter,具體用法很簡單,直接看代碼就可以啦~