转载请注明出处: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。

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

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

【凯子哥带你夯实应用层】使用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. SICK LMS111激光雷达的使用

    LMS111系列是SICK推出的一款用于室外区域防撞.测量及安防的激光扫描器.LMS111同西克其他扫描器一样,采用成熟的ToF原理,非接触式检测,且加入了最新的多次回波检测技术(两次回波),使得LM ...

  2. mysql字符生命周期

    mysql的字符集,对数据的导入导出很关键,明白自己集在不同阶段不同场景下的意义即为重要! 01.查看mysql当前字符集 show variables like '%cahr%'; 02.用户请求m ...

  3. $(document).ready() 和 window.onload 方法比较

    说明 页面加载文档完毕后,浏览器会通过 Javascript 为 DOM 元素添加事件. Javascript 使用 window.onload 方法,而 jQuery 使用 $(document). ...

  4. 【laravel5.4】安装predis

    1.服务器先安装redis-server,这是毋庸置疑的!!! 2.服务器开启redis-server,配置相关参数 3.laravel执行 : $  yourPhpPath composer.pha ...

  5. eclipse 找类的jar包方便工具

    经常在开发过程,因为使用到比较多的类库(jar文件),在开发时经常会找不到需要的类文件存放在哪个jar文件中,这时classlocator这个插件就带我们带来极大的方便,可以帮我很快速的找到我们需要的 ...

  6. 转载:librdkafka问题总结

    使用librdkafka过程中,遇到的一些问题,解决办法! 暂时先转载:form:http://blog.csdn.net/lybingo/article/details/52808192?locat ...

  7. ss is one another utility to investigate sockets(特适合大规模tcp链接)

    原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: ss is one another utility to investigate sockets(特适合大规模tcp链接) 具体的可以 ...

  8. IT技术需求建立时需考虑的因素

      2012-11-13 内容存档在evernote,笔记名"IT技术需求建立时需考虑的因素"

  9. 联想Thinkpad笔记本自带win10改win7图文教程

    一.准备工作: 1.备份转移硬盘所有文件 2.改装win7将删除所有分区,要恢复预装的win10系统需到售后 3.4G空间以上U盘,制作U盘PE启动盘 4.操作系统:联想Lenovo笔记本专用GHOS ...

  10. wait3和wait4函数(转)

    wait3和wait4函数除了可以获取子进程状态转变信息外,还可以获得子进程的资源使用信息. pid_t wait3 ( int *status, int option, struct rusage ...