【凯子哥带你夯实应用层】使用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 if语句
//if语句 //Test10.java import java.util.Scanner; public class Test16{ public static void main(String[] ...
- phoneGap+jquery mobile项目经验
最近一个月,一直在用phoneGap+jquery mobile来开发一项目. 下面谈谈自己在开发过程中遇到的一些问题以及解决方法. 开始选择框架时,曾试过采用其他框架做UI,例如chocol ...
- X-Forwarded-For 会少记录一次代理服务器的IP
X-Forwarded-For是一个Http请求头中的项目. 当一个请求经过代理时,X-Forwarded-For将被记录下来,规则如下: 假设用户U,通过代理服务器A,请求到服务器S, 那么X-Fo ...
- vijos 1006 晴天小猪历险记之Hill——数字三角形的终极变化
题目链接:https://vijos.org/p/1006 数字三角形原题看这里:http://www.cnblogs.com/huashanqingzhu/p/7326837.html 背景 在很久 ...
- JetBrains全系列在线激活中心pycharm
题记:有能力还是建议购买正版授权! 01.pycharm下载 https://www.jetbrains.com/pycharm/download/ https://download.jetbrai ...
- Mysql分页之limit用法与limit优化
Mysql limit分页语句用法 与Oracle和MS SqlServer相比,mysql的分页方法简单的让人想哭. --语法: SELECT * FROM table LIMIT [offset, ...
- Dubbo在开发中的一些常用配置
介绍Dubbo在开发中的一些常用配置,文中内容主要参考dubbo文档配置和示例两节,详细可移步访问 传送站 1. 属性配置方法及加载顺序 属性常用配置方法主要有三种: 第一种是通过启动时在虚拟机参数 ...
- QQ登录整合/oauth2.0认证-03-对第二节的代码改进
---------------------------目录---------------------------------- QQ登录整合/oauth2.0认证-01-申请appkey和appid ...
- 【已解决】mysql连接出错:ERROR 1040 (HY000): Too many connections
连接mysql,结果出错: ? 1 ERROR 1040 (HY000): Too many connections 去修改mysql的配置文件,然后添加: ? 1 2 3 4 5 6 7 8 9 1 ...
- ios中xml和html解析(封装)
下载地址 http://pan.baidu.com/share/link?shareid=2902188921&uk=923776187 GDataXML和TFHpple配置是一样的(配置方 ...