zoukankan      html  css  js  c++  java
  • 【凯子哥带你夯实应用层】使用ActionMode实现有删除动画的多选删除功能

        转载请注明出处: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没有多少知识点要说。咱们就简介下,然后上代码,这个功能主要事实上主要是逻辑麻烦点,也非常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

  • 相关阅读:
    iOS开发—block介绍
    iOS开发—页面传值汇总
    解决Xcode升级后一些Xcode插件不能使用的问题
    记录一些优秀的iOS第三方框架
    【转】iOS开发—SQLite的简单使用
    iOS—dictionary写入文件出现的几个问题
    NSUserDefaults 简介,使用 NSUserDefaults 存储自定义对象
    【原】自定义tableviewcell中多个button点击实现不同功能
    【转】自定义tableViewCell中button push viewcontroller的实现(delegate和Block)
    限制UITextField只可以输入数字
  • 原文地址:https://www.cnblogs.com/llguanli/p/8907164.html
Copyright © 2011-2022 走看看