转载请注明出处: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(){@Overridepublic boolean onCreateActionMode(ActionMode mode, Menu menu) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean onPrepareActionMode(ActionMode mode, Menu menu) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean onActionItemClicked(ActionMode mode, MenuItem item) {// TODO Auto-generated method stubreturn false;}@Overridepublic void onDestroyActionMode(ActionMode mode) {// TODO Auto-generated method stub}@Overridepublic void onItemCheckedStateChanged(ActionMode mode,int position, long id, boolean checked) {// TODO Auto-generated method stub}});

就5个方法,看名字也很好理解。

在onCreateActionMode()中,一般实现ActionMode下右侧的MenuItem配置,和标题设置,比如像下面这样

@Overridepublic 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一样,所以我们可以像下面这样

@Overridepublic 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;@Overrideprotected 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() {@Overridepublic boolean onPrepareActionMode(ActionMode mode, Menu menu) {return false;}@Overridepublic void onDestroyActionMode(ActionMode mode) {// 在退出ActionMode的时候调用,如果处于删除状态,就删除选中的数据,// 否则,重置所有选中的状态if (!isInDeleteMode) {for (Model model : mAdapter.models) {model.setChecked(false);}mCheckedPositions.clear();}isInActionMode = false;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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));}}@Overridepublic int getCount() {return models.size();}@Overridepublic Model getItem(int position) {return models.get(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic 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 {@Overridepublic 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,具体用法很简单,直接看代码就可以啦~

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

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

  1. 【凯子哥带你夯实应用层】都说“知乎”逼格高,我们来实现“知乎”回答详情页动画效果

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 2014已经远去,2015年的目标很简单,就是继续熟悉Android的上层API,虽然偶尔会为了某个问题去研 ...

  2. 【凯子哥带你夯实应用层】Android的Google官方设计指南(上)

    Android 设计规范 时间 2015.3.2 版本 V1.0 翻译 杨鹏 整理 赵凯强 本文章是我公司一个大牛之前的公司同事翻译的Android的Google官方设计指导,经过我整理而成,分享给大 ...

  3. 【凯子哥带你学Android】Andriod性能优化之列表卡顿——以“简书”APP为例

    这几天闲得无聊,就打开手机上的开发者模式里面的"GPU过度绘制"功能,看看别家的App做的咋样,然后很偶然的打开了"简书",然后就被它的过度绘制惊呆了,于是写了 ...

  4. 【凯子哥带你学Framework】Activity界面显示全解析

    前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明"写让大家都能看懂的Framework解析文章"的思想是基本正确的. ...

  5. 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(二)——大图显示模式、评论“盖楼”效果实现详解

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 在前一篇文章中,我们学习了如何进行逆向工程和TcpDump进行抓包,获取我们的数据接口,那么有了数据之后,我 ...

  6. 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(三)——使用GreenDao实现本地Sqlite缓存

    到目前为止,煎蛋的Android项目算是告一段落了,功能基本都已完成,那么今天,我就介绍一下在煎蛋这个项目里,是怎么完成数据缓存功能的.想看代码的请戳煎蛋项目的GITHUB地址 转载请注明出处:htt ...

  7. jdbc代码_凯哥带你从零学大数据系列之数据库篇---第三章:JDBC基础

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  8. map根据value值排序_凯哥带你从零学大数据系列之Java篇---第十九章:集合(Map+Collections)...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  9. ios 获取一个枚举的所有值_凯哥带你从零学大数据系列之Java篇---第十一章:枚举...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

最新文章

  1. cnocr训练_cnocr: 极简的中文OCR Python包
  2. java抓取新闻_【图片】【抓取】Java获取各大网站新闻【java吧】_百度贴吧
  3. php 鼠标点击图片放大,鼠标移入放大图片预览效果实现
  4. ionic2开发的仿外卖点餐系统(Ionic2+Angular2
  5. Spark的相关概念说明和检查点机制
  6. 解析IPostBackEventHandler和WebForm的事件机制
  7. vue中动态添加组件
  8. Linux Tomcat9 控制界面及管理配置
  9. ftp服务器向所有主机发送文件,文件传输FTP
  10. 36氪独家|京东零售宣布多位高管新任命,POP平台部门成整合重点
  11. Android NFC 门票系统手机端程序简介
  12. 一对一直播app源码开发的前端实现
  13. 2020年中考英语计算机考试,2020年中考英语听说测试考生问答
  14. Redis Expire 设置key过期时间
  15. 关于【商品计量单位以及这些计量单位换算】的设计
  16. 安装时提示用户在命令行上发出了EULAS_AGREED=1,表示不接受许可协议
  17. 【项目管理】项目选择与项目章程
  18. 计划策略70 之 MIXED MRP
  19. 我们使用的人工智能产品,大致分为六类,掌握以下几个名词,以备不时之需
  20. SSRF之GOPHER协议利用

热门文章

  1. 2019游戏开发学习路线图
  2. 浅谈FPGA有限状态机
  3. 广东电信IPTV机顶盒HG680-J私人定制过程
  4. HierarchyView
  5. VS2015开发OpenDDS实例(ACE_TAO_6.5.10+OpenDDS_3.12+ActivePerl-5.28)
  6. CCNA2.0笔记_STP
  7. 视频转文字怎么转?安利下面这三个方法给你
  8. Vue全家桶:路由 vue-router
  9. 窗体全屏 隐藏任务栏与菜单栏
  10. python中struct.unpack的用法