开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用
MultiChoiceBaseAdapter是一个可以多选的BaseAdapter,使用的方式相比来说扩展性更强!
使用方式:
1.布局文件
2.写一个类继承MultiChoiceBaseAdapter
3.实现内部的各个方法
4.设置数据源和视图
5.完成保存的回调方法
一、布局文件
listview_actionmode_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/actionMode_listView" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout>
item.xml
注意:这里值得注意的是添加了一个CheckBox,它的id很重要。如果是:@android:id/checkbox的话,用户点击这个checkbox的时候直接会进入可以多选的状态,如果是用其他的id的话,点击它就是普通的选择,不会触发多选状态。
<?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" /> <!-- CheckBox中一定要写上focusable="false"否则无法相应点击事件 @android:id/checkbox这个也一定要写,如果不写的话点击checkbox就不会触发多选状态 如果你不想要选中checkbox就触发多选状态的话,这里可以用自己定义的id就行 --> <CheckBox android:id="@android:id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|right" android:layout_weight="1" android:layout_marginLeft="40dp" android:textColor="#000000" android:focusable="false" android:visibility="gone" android:text="" /> </LinearLayout> </com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout>
二、继承MultiChoiceBaseAdapter
构造函数中推荐传入的是一个list对象,一个是因为可以方便的动态删除或者增加元素,还有一个是方便扩展。比如有一个对象Person传入一个List<Person>对象,然后用get(……)方法就可以进行相应的设置了。如果传入的是数组对象,就很难动态删除和增加了。
private class MultiBaseAdapter extends MultiChoiceBaseAdapter{ private List<String> mData; /** * 构造函数 * @param savedInstanceState */ public MultiBaseAdapter(Bundle savedInstanceState,List<String> data) { super(savedInstanceState); // TODO 自动生成的构造函数存根 mData = data; } /** * 创建ActionMode对象,必须返回true!!! */ @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.my_action_mode, menu); return true; } /** * item点击时处理的事件,从ActionMode.callback中继承过来的 */ @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if (item.getItemId() == R.id.menu_share) { Toast.makeText(getContext(), "分享了" + getCheckedItemCount() + "item", Toast.LENGTH_SHORT).show(); return true; } if (item.getItemId() == R.id.menu_discard) { //TODO:删除选中的元素 removeSelectedItems(); return true; } return false; } /** * 删除已经选中的items */ private void removeSelectedItems() { // http://stackoverflow.com/a/4950905/244576 List<Long> positions = new ArrayList<Long>(getCheckedItems()); Collections.sort(positions, Collections.reverseOrder()); for (long position : positions) { mData.remove((int)position); } finishActionMode(); } @Override public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) { // TODO 自动生成的方法存根 return false; } /** * 看适配器中有多少元素需要加载 */ @Override public int getCount() { // TODO 自动生成的方法存根 return mData.size(); } /** * 通过position来得到相应的item,这里返回object对象 */ @Override public Object getItem(int position) { // TODO 自动生成的方法存根 return mData.get(position); } /** * 通过position得到id */ @Override public long getItemId(int position) { // TODO 自动生成的方法存根 return position; } /** * 返回item的view对象 */ @Override protected View getViewImpl(int position, View convertView, ViewGroup parent) { if (convertView == null) { int layout = R.layout.item; LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(layout, parent, false); } ViewGroup group = (ViewGroup)convertView; ((TextView)group.findViewById(R.id.item_textView)).setText(mData.get(position)); ((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE); return group; } }
三、设置适配器和保存的方法
private ArrayList<String> items ; private MultiBaseAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { // TODO 自动生成的方法存根 super.onCreate(savedInstanceState); setContentView(R.layout.listview_actionmode_layout); String[] data = {"android","ios","wp","c++", "java","c#","javascript","vb", "delphi","PB","ASP","SQL"}; items = new ArrayList<String>(Arrays.asList(data)); ListView list = (ListView)findViewById(R.id.actionMode_listView); adapter = new MultiBaseAdapter(savedInstanceState, items); adapter.setAdapterView(list); adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { Toast.makeText(getApplicationContext(), "点击了"+items.get(position), 0).show(); } }); } @Override protected void onSaveInstanceState(Bundle outState) { adapter.save(outState); }
大功告成!!!
下面是全部代码:
BaseAdapterTestActivity.java
package com.kale.multichoiceadaptertest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.CheckBox; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.manuelpeinado.multichoiceadapter.normal.MultiChoiceBaseAdapter; /** * 4.0上的用activity * 并且导入 * import android.view.ActionMode; * import com.manuelpeinado.multichoiceadapter.normal.MultiChoiceBaseAdapter; * 兼容2.0导入ActionbarActivity * 并且导入 * import android.support.v7.view.ActionMode; * import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceBaseAdapter; */ /** * * @author:Jack Tony * @tips : * @date :2014-10-21 */ public class BaseAdapterTestActivity extends Activity{ private ArrayList<String> items ; private MultiBaseAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { // TODO 自动生成的方法存根 super.onCreate(savedInstanceState); setContentView(R.layout.listview_actionmode_layout); String[] data = {"android","ios","wp","c++", "java","c#","javascript","vb", "delphi","PB","ASP","SQL"}; items = new ArrayList<String>(Arrays.asList(data)); ListView list = (ListView)findViewById(R.id.actionMode_listView); adapter = new MultiBaseAdapter(savedInstanceState, items); adapter.setAdapterView(list); adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { Toast.makeText(getApplicationContext(), "点击了"+items.get(position), 0).show(); } }); } @Override protected void onSaveInstanceState(Bundle outState) { adapter.save(outState); } private class MultiBaseAdapter extends MultiChoiceBaseAdapter{ private List<String> mData; /** * 构造函数 * @param savedInstanceState */ public MultiBaseAdapter(Bundle savedInstanceState,List<String> data) { super(savedInstanceState); // TODO 自动生成的构造函数存根 mData = data; } /** * 创建ActionMode对象,必须返回true!!! */ @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.my_action_mode, menu); return true; } /** * item点击时处理的事件,从ActionMode.callback中继承过来的 */ @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if (item.getItemId() == R.id.menu_share) { Toast.makeText(getContext(), "分享了" + getCheckedItemCount() + "item", Toast.LENGTH_SHORT).show(); return true; } if (item.getItemId() == R.id.menu_discard) { //TODO:删除选中的元素 removeSelectedItems(); return true; } return false; } /** * 删除已经选中的items */ private void removeSelectedItems() { // http://stackoverflow.com/a/4950905/244576 List<Long> positions = new ArrayList<Long>(getCheckedItems()); Collections.sort(positions, Collections.reverseOrder()); for (long position : positions) { mData.remove((int)position); } finishActionMode(); } @Override public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) { // TODO 自动生成的方法存根 return false; } /** * 看适配器中有多少元素需要加载 */ @Override public int getCount() { // TODO 自动生成的方法存根 return mData.size(); } /** * 通过position来得到相应的item,这里返回object对象 */ @Override public Object getItem(int position) { // TODO 自动生成的方法存根 return mData.get(position); } /** * 通过position得到id */ @Override public long getItemId(int position) { // TODO 自动生成的方法存根 return position; } /** * 返回item的view对象 */ @Override protected View getViewImpl(int position, View convertView, ViewGroup parent) { if (convertView == null) { int layout = R.layout.item; LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(layout, parent, false); } ViewGroup group = (ViewGroup)convertView; ((TextView)group.findViewById(R.id.item_textView)).setText(mData.get(position)); ((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE); return group; } } }
开源项目MultiChoiceAdapter详解(一)——概要介绍
开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用
开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用
开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用
开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter
开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用