MulitChoiceNormalArrayAdapter是我自己定义的一个类,其实就是实现了MulitChoiceArrayAdapter,为什么做这个简单的实现类呢,因为这样我们在不用ActionMode的时候就不用每次要写一个类来继承MulitChoiceArrayAdapter了,直接实例化MulitChoiceNormalArrayAdapter即可。下面贴一个compat包下的MulitChoiceNormalArrayAdapter的源码。
MulitChoiceNormalArrayAdapter.java
package com.manuelpeinado.multichoiceadapter.compat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.content.Context; import android.os.Bundle; import android.support.v7.view.ActionMode; import android.view.Menu; import android.view.MenuItem; public class MulitChoiceNormalArrayAdapter<T> extends MultiChoiceArrayAdapter<T> { public MulitChoiceNormalArrayAdapter(Bundle savedInstanceState, Context context, int resource, int textViewResourceId) { super(savedInstanceState, context, resource, textViewResourceId); // TODO 自动生成的构造函数存根 } public MulitChoiceNormalArrayAdapter(Bundle savedInstanceState, Context context, int resource, int textViewResourceId, List<T> objects) { super(savedInstanceState, context, resource, textViewResourceId, objects); // TODO 自动生成的构造函数存根 } public MulitChoiceNormalArrayAdapter(Bundle savedInstanceState, Context context, int resource, int textViewResourceId, T[] objects) { this(savedInstanceState,context,resource,textViewResourceId,new ArrayList<T>(Arrays.asList(objects))); // TODO 自动生成的构造函数存根 } @Override public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) { // TODO 自动生成的方法存根 return false; } @Override public boolean onCreateActionMode(ActionMode arg0, Menu arg1) { // TODO 自动生成的方法存根 return false; } @Override public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) { // TODO 自动生成的方法存根 return false; } }
好了,知道了这个后我们来看怎么简单的来使用这个适配器进行多选。
1.写布局文件
2.实例化MultiChoiceAdapter
3.设置showActionMode(false)来表示不使用ActionMode
4.setAdapterView();来设置要用适配器的view对象
5.设置下监听器来进行各种扩展的操作
一、布局文件
listview_normal_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/normal_listView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" > </ListView> <LinearLayout android:id="@+id/setting_linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom"> <Button android:id="@+id/selectAll_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选" android:layout_weight="1" android:onClick="buttonListener"/> <Button android:id="@+id/cancle_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="取消" android:layout_weight="1" android:onClick="buttonListener"/> <Button android:id="@+id/delete_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="删除" android:onClick="buttonListener"/> <Button android:id="@+id/share_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="分享" android:layout_weight="1" android:onClick="buttonListener"/> </LinearLayout> </LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?> <com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/custom_list_item_background" android:orientation="horizontal"> <!-- 上面必须要用自定义的layout,否则不会有选中的效果!!! --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:orientation="horizontal" > <TextView android:id="@+id/item_textView" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:layout_gravity="center_vertical" android:textColor="#000000" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> </com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout>
二、实现适配器和绑定适配器
final LinearLayout settingLL = (LinearLayout)findViewById(R.id.setting_linearLayout); settingLL.setVisibility(View.GONE); ListView normalListView = (ListView)findViewById(R.id.normal_listView); String[] data = {"android","ios","wp","c++", "java","c#","javascript","vb", "delphi","PB","ASP","SQL"}; //ArrayList<String> items = new ArrayList<>(Arrays.asList(data)); normalAdapter = new MulitChoiceNormalArrayAdapter<String>(savedInstanceState, getApplicationContext(), R.layout.item, R.id.item_textView, data); normalAdapter.showActionMode(false);//设置为显示actionmode的普通模式 normalAdapter.setAdapterView(normalListView); normalAdapter.setOnItemClickListener(new MyItemClick(normalAdapter));
三、写一些回调方法来优化,比如选中时点击返回后取消选中
@Override protected void onSaveInstanceState(Bundle outState) { normalAdapter.save(outState); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK ) { if (normalAdapter.getCheckedItemCount() > 0) { cancleAll(normalAdapter); return true; } } return super.onKeyDown(keyCode, event); }
四、绑定监听器
setOnItemClickListener是在item被点击时触发的
setOnSelectedStateChangeListener是item被选中或者取消选中时触发的
normalAdapter.setOnItemClickListener(new MyItemClick(normalAdapter)); normalAdapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() { /** * checkedItemCount = 已经选中的item数目 */ @Override public void onSelectedStateChanged(int checkedItemCount) { if (checkedItemCount != 0) { settingLL.setVisibility(View.VISIBLE); } else { settingLL.setVisibility(View.GONE); } } }); /** * @author:Jack Tony * @tips :点击事件的监听器 * @date :2014-10-20 */ private class MyItemClick implements OnItemClickListener{ private MultiChoiceArrayAdapter<String> mAdapter; public MyItemClick(MultiChoiceArrayAdapter<String> adapter) { mAdapter = adapter; } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { Toast.makeText(getApplicationContext(), "点击了: " + mAdapter.getItem(position), Toast.LENGTH_SHORT).show(); } }
五、通过按钮进行操作(这是扩展性的重要体现)
public void buttonListener(View v) { switch (v.getId()) { case R.id.selectAll_button: selectAll(normalAdapter); break; case R.id.cancle_button: cancleAll(normalAdapter); break; case R.id.delete_button: delectItems(normalAdapter); break; case R.id.share_button: Toast.makeText(getApplicationContext(), "分享"+Arrays.toString(getSelectedItems(normalAdapter)), 1).show(); cancleAll(normalAdapter); break; default: break; } } /** * 全选 * @param adapter */ private void selectAll(MultiChoiceArrayAdapter<String> adapter) { for (int i = 0; i < adapter.getCount(); ++i) { adapter.setItemChecked(i, true); } } /** * 取消所有选择效果 * @param adapter */ private void cancleAll(MultiChoiceArrayAdapter<String> adapter) { for (int i = 0; i < adapter.getCount(); ++i) { adapter.setItemChecked(i, false); } } /** * 得到已经选中的items * @param adapter * @return */ private String[] getSelectedItems(MultiChoiceArrayAdapter<String> adapter) { //得到选中的items Set<Long> selection = adapter.getCheckedItems(); String[] items = new String[selection.size()]; int i = 0; for (long position : selection) { items[i++] = adapter.getItem((int)position); } return items; } /** * 删除已经选中的items * @param adapter */ private void delectItems(MultiChoiceArrayAdapter<String> adapter) { //通过判断名字来remove掉这些items for (String item : getSelectedItems(adapter)) { /** * 这里用remove时要注意传入适配器的不能是String[] items对象。否则会报错 * 这里我已经在构造函数中进行了处理,传入String数组也不会出错了~ */ adapter.remove(item); } cancleAll(adapter); }
全部搞定了!!!
下面是全部代码:
package com.kale.multichoiceadaptertest; import java.util.Arrays; import java.util.Set; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import com.manuelpeinado.multichoiceadapter.base.OnSelectedStateChangeListener; import com.manuelpeinado.multichoiceadapter.compat.MulitChoiceNormalArrayAdapter; import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceArrayAdapter; /** * 如果不用到ActionMode对象的话可以放心大胆的继承activity,也不用导入ActionMode了。 * * 其实在不用ActionMode时导入 * import com.manuelpeinado.multichoiceadapter.normal.MulitChoiceNormalArrayAdapter; * import com.manuelpeinado.multichoiceadapter.normal.MultiChoiceArrayAdapter; * 或者是 * import com.manuelpeinado.multichoiceadapter.compat.MulitChoiceNormalArrayAdapter; * import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceArrayAdapter; * 都一样的,只是为了以后的扩展,还是按需导入吧。 * 4.0以上的导入normal包下面的,兼容2.0的导入compat包下的 */ public class ArrayAdapterNormalTestActivity extends Activity{ MulitChoiceNormalArrayAdapter<String> normalAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview_normal_layout); final LinearLayout settingLL = (LinearLayout)findViewById(R.id.setting_linearLayout); settingLL.setVisibility(View.GONE); ListView normalListView = (ListView)findViewById(R.id.normal_listView); String[] data = {"android","ios","wp","c++", "java","c#","javascript","vb", "delphi","PB","ASP","SQL"}; //ArrayList<String> items = new ArrayList<>(Arrays.asList(data)); normalAdapter = new MulitChoiceNormalArrayAdapter<String>(savedInstanceState, getApplicationContext(), R.layout.item, R.id.item_textView, data); normalAdapter.showActionMode(false);//设置为显示actionmode的普通模式 normalAdapter.setAdapterView(normalListView); normalAdapter.setOnItemClickListener(new MyItemClick(normalAdapter)); normalAdapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() { /** * checkedItemCount = 已经选中的item数目 */ @Override public void onSelectedStateChanged(int checkedItemCount) { if (checkedItemCount != 0) { settingLL.setVisibility(View.VISIBLE); } else { settingLL.setVisibility(View.GONE); } } }); } @Override protected void onSaveInstanceState(Bundle outState) { normalAdapter.save(outState); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK ) { if (normalAdapter.getCheckedItemCount() > 0) { cancleAll(normalAdapter); return true; } } return super.onKeyDown(keyCode, event); } public void buttonListener(View v) { switch (v.getId()) { case R.id.selectAll_button: selectAll(normalAdapter); break; case R.id.cancle_button: cancleAll(normalAdapter); break; case R.id.delete_button: delectItems(normalAdapter); break; case R.id.share_button: Toast.makeText(getApplicationContext(), "分享"+Arrays.toString(getSelectedItems(normalAdapter)), 1).show(); cancleAll(normalAdapter); break; default: break; } } /** * 全选 * @param adapter */ private void selectAll(MultiChoiceArrayAdapter<String> adapter) { for (int i = 0; i < adapter.getCount(); ++i) { adapter.setItemChecked(i, true); } } /** * 取消所有选择效果 * @param adapter */ private void cancleAll(MultiChoiceArrayAdapter<String> adapter) { for (int i = 0; i < adapter.getCount(); ++i) { adapter.setItemChecked(i, false); } } /** * 得到已经选中的items * @param adapter * @return */ private String[] getSelectedItems(MultiChoiceArrayAdapter<String> adapter) { //得到选中的items Set<Long> selection = adapter.getCheckedItems(); String[] items = new String[selection.size()]; int i = 0; for (long position : selection) { items[i++] = adapter.getItem((int)position); } return items; } /** * 删除已经选中的items * @param adapter */ private void delectItems(MultiChoiceArrayAdapter<String> adapter) { //通过判断名字来remove掉这些items for (String item : getSelectedItems(adapter)) { /** * 这里用remove时要注意传入适配器的不能是String[] items对象。否则会报错 * 这里我已经在构造函数中进行了处理,传入String数组也不会出错了~ */ adapter.remove(item); } cancleAll(adapter); } /** * @author:Jack Tony * @tips :点击事件的监听器 * @date :2014-10-20 */ private class MyItemClick implements OnItemClickListener{ private MultiChoiceArrayAdapter<String> mAdapter; public MyItemClick(MultiChoiceArrayAdapter<String> adapter) { mAdapter = adapter; } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { Toast.makeText(getApplicationContext(), "点击了: " + mAdapter.getItem(position), Toast.LENGTH_SHORT).show(); } } }
开源项目MultiChoiceAdapter详解(一)——概要介绍
开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用
开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用
开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用
开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter
开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用