【凯子哥带你夯实应用层】使用ActionMode实现有删除动画的多选删除功能

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 

    ActionMode是3.0之后。官方推荐的一种上下文菜单的实现方式,在之前一直用的是Context Menu,今天这篇文章简介一下ActionMode,并实现多选删除功能。

    假设要在ListView这类控件中实现多选,我们能够通过设置setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL)来实现,然后通过设置setMultiChoiceModeListener之后,就能够开启ActionMode。

ActionMode并非一个View。仅仅是一个操作模式,所以我们用的时候不能依照View的使用方法来使用。

    以下是实现的效果图

【凯子哥带你夯实应用层】使用ActionMode实现有删除动画的多选删除功能

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb2thaXFpYW5nMTk5Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

    这个和GMail的删除是不是非常像?

    由于ActionMode没有多少知识点要说。咱们就简介下,然后上代码,这个功能主要事实上主要是逻辑麻烦点,也非常easy。

    设置完多选模式监听器之后,我们须要实现以下的方法

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。详细使用方法非常easy。直接看代码就能够啦~

    下载地址:https://github.com/ZhaoKaiQiang/MultyChoiceDemo

上一篇:Android Handler使用实例


下一篇:js判断微信浏览器