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

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

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

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

    以下是实现的效果图

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

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

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

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

  1. mListView.setMultiChoiceModeListener(new MultiChoiceModeListener(){
  2.  
  3. @Override
  4. public boolean onCreateActionMode(ActionMode mode, Menu menu) {
  5. // TODO Auto-generated method stub
  6. return false;
  7. }
  8.  
  9. @Override
  10. public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
  11. // TODO Auto-generated method stub
  12. return false;
  13. }
  14.  
  15. @Override
  16. public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
  17. // TODO Auto-generated method stub
  18. return false;
  19. }
  20.  
  21. @Override
  22. public void onDestroyActionMode(ActionMode mode) {
  23. // TODO Auto-generated method stub
  24.  
  25. }
  26.  
  27. @Override
  28. public void onItemCheckedStateChanged(ActionMode mode,
  29. int position, long id, boolean checked) {
  30. // TODO Auto-generated method stub
  31.  
  32. }
  33.  
  34. });

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

    在onCreateActionMode()中,一般实现ActionMode下右側的MenuItem配置。和标题设置。比方像以下这样

  1. @Override
  2. public boolean onCreateActionMode(ActionMode mode, Menu menu) {
  3. // 在进入ActionMode的时候调用
  4. MenuInflater inflater = mode.getMenuInflater();
  5. inflater.inflate(R.menu.menu_delete, menu);
  6. mode.setTitle("Delete");
  7. isInActionMode = true;
  8. isInDeleteMode = false;
  9.  
  10. return true;
  11. }

    onActionItemClicked则是在我们设置的MenuItem点击之后调用,和ActionBar里面的MenuItem一样。所以我们能够像以下这样

  1. @Override
  2. public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
  3.  
  4. // 当listview中的item被点击的时候调用
  5. if (item.getItemId() == R.id.action_delete) {
  6. mAnimateDismissAdapter.animateDismiss(mCheckedPositions);
  7. isInDeleteMode = true;
  8. mode.finish();
  9. return true;
  10. }
  11.  
  12. return false;
  13. }

    onItemCheckedStateChanged则是我们的listview的item点击的时候调用,我们能够依据position和checked进行逻辑操作。

    基本这几个方法就基本满足我们的功能了,以下是完整的演示样例代码

  1. package com.imooc.multychoice;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Iterator;
  5.  
  6. import android.app.Activity;
  7. import android.os.Bundle;
  8. import android.view.ActionMode;
  9. import android.view.Menu;
  10. import android.view.MenuInflater;
  11. import android.view.MenuItem;
  12. import android.view.View;
  13. import android.view.ViewGroup;
  14. import android.widget.AbsListView;
  15. import android.widget.AbsListView.MultiChoiceModeListener;
  16. import android.widget.BaseAdapter;
  17. import android.widget.CheckBox;
  18. import android.widget.ListView;
  19. import android.widget.TextView;
  20.  
  21. import com.haarman.listviewanimations.itemmanipulation.AnimateDismissAdapter;
  22. import com.haarman.listviewanimations.itemmanipulation.OnDismissCallback;
  23. import com.imooc.multychoice.R;
  24.  
  25. public class MainActivity extends Activity {
  26.  
  27. protected static final String TAG = "TAG";
  28. private ListView mListView;
  29. private MultyAdapter mAdapter;
  30. // 是否处于ActionMode模式
  31. private boolean isInActionMode;
  32. private boolean isInDeleteMode = false;
  33. private AnimateDismissAdapter<Model> mAnimateDismissAdapter;
  34. private ArrayList<Integer> mCheckedPositions;
  35.  
  36. @Override
  37. protected void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. setContentView(R.layout.activity_main);
  40.  
  41. mListView = (ListView) findViewById(R.id.lv);
  42. mAdapter = new MultyAdapter();
  43. mCheckedPositions = new ArrayList<Integer>();
  44.  
  45. mAnimateDismissAdapter = new AnimateDismissAdapter<MainActivity.Model>(
  46. mAdapter, new MyDismissCallBack());
  47. mAnimateDismissAdapter.setAbsListView(mListView);
  48. mListView.setAdapter(mAnimateDismissAdapter);
  49.  
  50. mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
  51.  
  52. mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
  53.  
  54. @Override
  55. public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
  56. return false;
  57. }
  58.  
  59. @Override
  60. public void onDestroyActionMode(ActionMode mode) {
  61.  
  62. // 在退出ActionMode的时候调用。假设处于删除状态。就删除选中的数据,
  63. // 否则,重置全部选中的状态
  64. if (!isInDeleteMode) {
  65. for (Model model : mAdapter.models) {
  66. model.setChecked(false);
  67. }
  68. mCheckedPositions.clear();
  69. }
  70.  
  71. isInActionMode = false;
  72.  
  73. }
  74.  
  75. @Override
  76. public boolean onCreateActionMode(ActionMode mode, Menu menu) {
  77. // 在进入ActionMode的时候调用
  78. MenuInflater inflater = mode.getMenuInflater();
  79. inflater.inflate(R.menu.menu_delete, menu);
  80. mode.setTitle("Delete");
  81. isInActionMode = true;
  82. isInDeleteMode = false;
  83.  
  84. return true;
  85. }
  86.  
  87. @Override
  88. public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
  89.  
  90. // 当listview中的item被点击的时候调用
  91. if (item.getItemId() == R.id.action_delete) {
  92. mAnimateDismissAdapter.animateDismiss(mCheckedPositions);
  93. isInDeleteMode = true;
  94. mode.finish();
  95. return true;
  96. }
  97.  
  98. return false;
  99. }
  100.  
  101. @Override
  102. public void onItemCheckedStateChanged(ActionMode mode,
  103. int position, long id, boolean checked) {
  104.  
  105. // 当item的选中状态被选中的时候调用
  106. mAdapter.models.get(position).setChecked(checked);
  107. mAdapter.notifyDataSetChanged();
  108. mode.setSubtitle(mListView.getCheckedItemCount()
  109. + " item selected");
  110.  
  111. if (mCheckedPositions.contains(position) && !checked) {
  112. mCheckedPositions.remove(Integer.valueOf(position));
  113. } else {
  114. mCheckedPositions.add(position);
  115. }
  116.  
  117. }
  118. });
  119.  
  120. }
  121.  
  122. private class MultyAdapter extends BaseAdapter {
  123.  
  124. private ArrayList<Model> models;
  125.  
  126. public MultyAdapter() {
  127.  
  128. models = new ArrayList<Model>();
  129. for (int i = 0; i < 20; i++) {
  130. models.add(new Model("I'm " + i));
  131. }
  132.  
  133. }
  134.  
  135. @Override
  136. public int getCount() {
  137. return models.size();
  138. }
  139.  
  140. @Override
  141. public Model getItem(int position) {
  142. return models.get(position);
  143. }
  144.  
  145. @Override
  146. public long getItemId(int position) {
  147. return 0;
  148. }
  149.  
  150. @Override
  151. public View getView(int position, View convertView, ViewGroup parent) {
  152.  
  153. ViewHolder viewHolder;
  154.  
  155. Model model = mAdapter.models.get(position);
  156.  
  157. if (convertView == null) {
  158.  
  159. convertView = getLayoutInflater().inflate(
  160. R.layout.item_multy_choice, parent, false);
  161.  
  162. viewHolder = new ViewHolder();
  163.  
  164. viewHolder.tv = (TextView) convertView.findViewById(R.id.tv);
  165. viewHolder.chb = (CheckBox) convertView.findViewById(R.id.chb);
  166. convertView.setTag(viewHolder);
  167. } else {
  168. viewHolder = (ViewHolder) convertView.getTag();
  169. }
  170.  
  171. viewHolder.tv.setText(model.getTitle());
  172. viewHolder.chb.setChecked(model.isChecked());
  173. viewHolder.chb.setVisibility(isInActionMode ? View.VISIBLE
  174. : View.GONE);
  175.  
  176. return convertView;
  177. }
  178. }
  179.  
  180. private static class ViewHolder {
  181. TextView tv;
  182. CheckBox chb;
  183. }
  184.  
  185. /**
  186. * 測试Model
  187. *
  188. * @author zhaokaiqiang
  189. *
  190. */
  191. private class Model {
  192.  
  193. private String title;
  194.  
  195. private boolean isChecked;
  196.  
  197. public Model(String title) {
  198. this.title = title;
  199. isChecked = false;
  200. }
  201.  
  202. public String getTitle() {
  203. return title;
  204. }
  205.  
  206. public boolean isChecked() {
  207. return isChecked;
  208. }
  209.  
  210. public void setChecked(boolean isChecked) {
  211. this.isChecked = isChecked;
  212. }
  213.  
  214. }
  215.  
  216. private class MyDismissCallBack implements OnDismissCallback {
  217.  
  218. @Override
  219. public void onDismiss(AbsListView arg0, int[] arg1) {
  220.  
  221. mCheckedPositions.clear();
  222.  
  223. Iterator<Model> iterator = mAdapter.models.iterator();
  224. while (iterator.hasNext()) {
  225. if (iterator.next().isChecked()) {
  226. // 删除选中的元素
  227. iterator.remove();
  228. }
  229. }
  230. mAdapter.notifyDataSetChanged();
  231. }
  232. }
  233.  
  234. }

    在上面的代码中。为了实现动画效果,我使用了开源项目ListViewAnimation中的AnimationDismissAdapter。详细使用方法非常easy。直接看代码就能够啦~

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

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

  1. 【凯子哥带你夯实应用层】使用ActionProvider实现子菜单时遇到的一个坑

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 近期在重温Android基础.在看到ActionProvider的时候遇到一个坑.分享到大家,避免入坑. 首 ...

  2. 【凯子哥带你学Framework】Activity启动过程全解析

    It’s right time to learn Android’s Framework ! 前言 学习目标 写作方式 主要对象功能介绍 主要流程介绍 zygote是什么有什么作用 SystemSer ...

  3. 【凯子哥带你学Framework】Activity界面显示全解析(下)

    咱们接着上篇继续讲,上篇没看的请戳:[凯子哥带你学Framework]Activity界面显示全解析(上) 如何验证上一个问题 首先,说明一下运行条件: //主题 name="AppThem ...

  4. 【转载】【凯子哥带你学Framework】Activity启动过程全解析

    It's right time to learn Android's Framework ! 前言 一个App是怎么启动起来的? App的程序入口到底是哪里? Launcher到底是什么神奇的东西? ...

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

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

  6. 【转载】【凯子哥带你学Framework】Activity界面显示全解析(下)

    如何验证上一个问题 首先,说明一下运行条件 //主题 name="AppTheme" parent="@android:style/Theme.Holo.Light.No ...

  7. 凯哥带你用python撸算法之雪花算法

    import time class Snow(object): def __init__(self, idx=None): init_date = time.strptime('2010-01-01 ...

  8. mysql 数据操作 多表查询 子查询 带IN关键字的子查询

    1 带IN关键字的子查询 #查询平均年龄在25岁以上的部门名关键点部门名 以查询员工表的dep_id的结果 当作另外一条sql语句查询条件使用 in (sql语句) mysql ; +-------- ...

  9. mysql 数据操作 多表查询 子查询 带比较运算符的子查询

    带比较运算符的子查询 #比较运算符:=.!=.>.>=.<.<=.<> #查询大于所有人平均年龄的员工名与年龄 思路 先拿到所有人的平均年龄然后 再用另外一条sql ...

随机推荐

  1. ACE .i .inl文件(转)

    在ACE的源代码目录里,有源文件.cpp.头文件.h,我们还发现有以.i和.inl为扩展名的文件.其实,以.i和.inl为扩展名的文件是ACE源码中inline函数的存放形式. 在说明ACE中为什么采 ...

  2. Java通过Fork/Join来优化并行计算

    Java代码: package Threads; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Recur ...

  3. java 生成二维码、可带LOGO、可去白边

      1.准备工作 所需jar包: JDK 1.6: commons-codec-1.11.jar core-2.2.jar javase-2.2.jar JDK 1.7: commons-codec- ...

  4. Lotus Domino开发心得(一)

    —- Lotus Domino 是当今办公自动化系统的主流开发平台之一,目前大部分企业和机构都在使用Lotus Domino 开发自己的无纸办公系统.在开发过程中,我积累了一些小技巧,现在公布出来,希 ...

  5. 转 安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法

    ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':/home/king/php-5.2.13/ext/iconv/ ...

  6. Java中的Random()函数 【转载】

        今天在做Java练习的时候注意到了Java里面的一个随机函数——Random,刚开始只是知道这个函数具有随机取值的作用,于是上网搜索了资料一番,做了一下一些关于Random函数的总结:   J ...

  7. ContentResolver.query()—>buildQueryString()

    Cursor cursor = context.getContentResolver().query(Sms.CONTENT_URI,         new String[]{"threa ...

  8. Swift3 文件操作常用方法汇总

    基于swift3的一些常用文件操作方法: 1.创建文件(文件夹) 2.读取文件(根据名称) 3.读取文件(根据路径) 4.判断文件是否存在(根据名称) 5.判断文件是否存在(根据路径) 6.删除指定名 ...

  9. 使用Cygwin登录Raspberry PI

    偿试了很多ssh终端程序,像ScureCRT,Putty,SSHSecureShellClient,SSH Client Tunnelier,每个工具都有自己的特点,putty对中文的支持还算好的,其 ...

  10. iOS 播放远程网络音乐的核心技术点

    一.前言 这两天做了个小项目涉及到了远程音乐播放,因为第一次做这种音乐项目,边查资料边做,其中涉及到主要技术点有: 如何播放远程网络音乐 如何切换当前正在播放中的音乐资源 如何监听音乐播放的各种状态( ...