【凯子哥带你夯实应用层】使用ActionMode实现有删除动画的多选删除功能
转载请注明出处: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。直接看代码就能够啦~
【凯子哥带你夯实应用层】使用ActionMode实现有删除动画的多选删除功能的更多相关文章
- 【凯子哥带你夯实应用层】使用ActionProvider实现子菜单时遇到的一个坑
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 近期在重温Android基础.在看到ActionProvider的时候遇到一个坑.分享到大家,避免入坑. 首 ...
- 【凯子哥带你学Framework】Activity启动过程全解析
It’s right time to learn Android’s Framework ! 前言 学习目标 写作方式 主要对象功能介绍 主要流程介绍 zygote是什么有什么作用 SystemSer ...
- 【凯子哥带你学Framework】Activity界面显示全解析(下)
咱们接着上篇继续讲,上篇没看的请戳:[凯子哥带你学Framework]Activity界面显示全解析(上) 如何验证上一个问题 首先,说明一下运行条件: //主题 name="AppThem ...
- 【转载】【凯子哥带你学Framework】Activity启动过程全解析
It's right time to learn Android's Framework ! 前言 一个App是怎么启动起来的? App的程序入口到底是哪里? Launcher到底是什么神奇的东西? ...
- 【凯子哥带你学Framework】Activity界面显示全解析
前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明“写让大家都能看懂的Framework解析文章”的思想是基本正确的. 我个人觉得,深入分 ...
- 【转载】【凯子哥带你学Framework】Activity界面显示全解析(下)
如何验证上一个问题 首先,说明一下运行条件 //主题 name="AppTheme" parent="@android:style/Theme.Holo.Light.No ...
- 凯哥带你用python撸算法之雪花算法
import time class Snow(object): def __init__(self, idx=None): init_date = time.strptime('2010-01-01 ...
- mysql 数据操作 多表查询 子查询 带IN关键字的子查询
1 带IN关键字的子查询 #查询平均年龄在25岁以上的部门名关键点部门名 以查询员工表的dep_id的结果 当作另外一条sql语句查询条件使用 in (sql语句) mysql ; +-------- ...
- mysql 数据操作 多表查询 子查询 带比较运算符的子查询
带比较运算符的子查询 #比较运算符:=.!=.>.>=.<.<=.<> #查询大于所有人平均年龄的员工名与年龄 思路 先拿到所有人的平均年龄然后 再用另外一条sql ...
随机推荐
- Java JDBC编程套路教程
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5847020.html 学习Java开发,一个必须掌握的知识点,就是数据库操作.当程序需要用到的数据达到一定程 ...
- minimum-path-sum-动态规划
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...
- wwindows文件放入linux后多出换行符
将 windows文件移到linux系统下会在文件行末尾多了一个换行符^M 使用命令cat -v tmp.c可以看到每行后边有^M字符 为了解决这个问题,我们用如下命令:touch love_tmp. ...
- Linux修改系统主机名
Linux修改系统主机名 一.查看主机名 [root@xqzt ~]# uname -n xqzt [root@xqzt ~]# hostname xqzt 二.修改hostname的四种方式? ...
- Java通过在主循环中判断Boolean来停止线程
Java代码: package Threads; /** * Created by Frank */ public class StopBoolean extends Thread { // 确保变化 ...
- golang 垃圾回收机制
用任何带 GC 的语言最后都要直面 GC 问题.在以前学习 C# 的时候就被迫读了一大堆 .NET Garbage Collection 的文档.最近也学习了一番 golang 的垃圾回收机制,在这里 ...
- quartz持久化部署实现
http://blog.csdn.net/wxniitxueyuan/article/details/50477712
- JavaScript callback function 回调函数的理解
来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...
- http和websocket共用同一端口
webpack热部署相关的插件 webpack-hot-middleware:是模块热替换插件,可以避免网页刷新.这个功能并不重要,因为我们可以手动刷新. webpack-dev-middleware ...
- 使用Cygwin登录Raspberry PI
偿试了很多ssh终端程序,像ScureCRT,Putty,SSHSecureShellClient,SSH Client Tunnelier,每个工具都有自己的特点,putty对中文的支持还算好的,其 ...