先上效果图:
html
//设置多选模式,下面的方法基于设置多选模式 list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); //获取Item选择状态: list.isItemChecked(i); //设置Item选择状态 list.setItemChecked(i, true); //清除所有选中状态 list.clearChoices();
多选模式下,ListView在触发OnItemClick时会设置Item为true,再点一次为false,java
咱们只需建立一个isMultiplSelectionMode来传递判断当前为多选模式,android
在全选时遍历list.setItemChecked()为true;app
反选时遍历list.isItemChecked(i)为true的set为false,false则为true,ide
删除时直接遍历list.isItemChecked(i)为true的在适配器上直接remove删除便可工具
咱们知道ListView继承AbsListView,
经过查看他的源码的isItemChecked方法,能够看到优化
... public boolean isItemChecked(int position) { if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) { return mCheckStates.get(position); } return false; } ...
首先判断了当前选择模式不等于默认的单选模式 && mCheckStates
不为空的时候从这个mCheckStates
去获取当前的item的选择状态,那咱们再来看看这个mCheckStates
究竟是什么?this
/** * Running state of which positions are currently checked */ SparseBooleanArray mCheckStates;
mCheckStates是SparseBooleanArray的实例,SparseBooleanArray实现了Cloneable接口,再往下就离题了,如今知道了mCheckStates本质是一个保存着Boolean的Array,而且这个Array与Items有关系,setItemChecked/isItemChecked都使用了mCheckStates,获取的就是Item的状态,逻辑他已经帮咱们写好,咱们只用用好isItemChecked便可。
(好像说了和没说同样,尴尬了|;)debug
activity_main.xml3d
先界面:1个显示选择个数的TextView,3个Button,1个ListView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:visibility="gone" android:id="@+id/ItemToolBar" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="选择了0项" android:id="@+id/counttext"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选" android:id="@+id/all"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="反选" android:id="@+id/unall"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除" android:id="@+id/del"/> </LinearLayout> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/mylistview"/> </LinearLayout>
listview_item.xml
固然还有Item项的界面,简单点,两个TextView,一个标题,一个内容
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/lv_text1"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Small Text" android:textAppearance="?android:attr/textAppearanceSmall" android:id="@+id/lv_text2"/> </LinearLayout>
MyAdapter.java
ListView的适配器,重写了getView方法,让当前可视部分的项目状态为选中时改变背景颜色,关于geiView的ViewHolder部分能够看这的文章【Android开发中经常使用的ListView列表的优化方式ViewHolder】,简而言之就是一种列表优化方式。
public class MyAdapter extends BaseAdapter { public ArrayList<HashMap<String, Object>> balistItem = new ArrayList<HashMap<>>(); @Override public int getCount() { return balistItem.size(); } @Override public long getItemId(int p1) { return p1); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); convertView = View.inflate(MainActivity.CONTEXT, R.layout.listview_item, null); viewHolder.title = convertView.findViewById(R.id.lv_text1); viewHolder.text = convertView.findViewById(R.id.lv_text2); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag(); } viewHolder.title.setText(balistItem.get(position).get("标题").toString()); viewHolder.text.setText(balistItem.get(position).get("内容").toString()); //判断position位置是否被选中,改变颜色 if (MainActivity.list.isItemChecked(position) && MainActivity.isMultipleSelectionMode) { convertView.setBackgroundColor(0xffff521d); } else { convertView.setBackgroundColor(0xff1E90FF); } return convertView; } public MyAdapter(List<? extends Map<String, ?>> data) { this.balistItem = (ArrayList<HashMap<String, Object>>) data; } private static class ViewHolder { TextView title; TextView text; public static ViewHolder newsInstance(View convertView) { ViewHolder holder = (ViewHolder) convertView.getTag(); if (holder == null) { holder = new ViewHolder(); holder.title = convertView.findViewById(R.id.lv_text1); holder.text = convertView.findViewById(R.id.lv_text2); convertView.setTag(holder); } return holder; } } }
MainActivity.java
建立数据,并添加至适配器,设置长按进入多选模式,
public class MainActivity extends AppCompatActivity { static ListView list; static MyAdapter listItemAdapter;//适配器 static boolean isMultipleSelectionMode;//判断进入多选模式 public static ArrayList<HashMap<String, Object>> AdapterList = new ArrayList<>(); //数据 public static Context CONTEXT; TextView counttext; LinearLayout ItemToolBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CONTEXT = this.getApplicationContext(); //初始化数据 initData(); counttext = this.findViewById(R.id.counttext);//选中时更改的textview ItemToolBar = this.findViewById(R.id.ItemToolBar);//多选模式的工具栏 list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listItemAdapter = new MyAdapter(AdapterList); //新建并配置ArrayAapeter list.setAdapter(listItemAdapter); list.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> p, View v, int index, long arg3) { if (isMultipleSelectionMode) { setCountChange(); } listItemAdapter.notifyDataSetChanged(); } }); list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long itemId) { if (isMultipleSelectionMode) { ItemToolBar.setVisibility(View.GONE); isMultipleSelectionMode = false; list.clearChoices();//取消选中状态 Toast.makeText(CONTEXT, "退出多选模式", Toast.LENGTH_LONG).show(); } else { ItemToolBar.setVisibility(View.VISABLE); isMultipleSelectionMode =true; listItemAdapter.notifyDataSetChanged(); //多选模式 Toast.makeText(CONTEXT, "进入多选模式", Toast.LENGTH_LONG).show(); for(int i = 0;i < listItemAdapter.balistItem.size();i++){ Log.d("del","Item" + i + "的状态:" + list.isItemChecked(i)); } return true; } listItemAdapter.notifyDataSetChanged(); setCountChange(); return false; } }); //设置按钮单机事件绑定 setButtonClick(); } public void setCountChange(){ counttext.setText("选中了" + list.getCheckedItemCount() +"项"); } public void initData(){ list = this.findViewById(R.id.mylistview); for(int i = 0;i< 5;i++){ HashMap<String,Object> map = new HashMap<>(); map.put("标题","这是标题" + i); map.put("内容","这是内容" + i); AdapterList.add(map); } } public void setButtonClick(){ Button all = this.findViewById(R.id.all); Button unall = this.findViewById(R.id.unall); Button del = this.findViewById(R.id.del); all.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for(int i = 0;i < listItemAdapter.balistItem.size();i++){ list.setItemChecked(i,true); } setCountChange(); } }); unall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for(int i = 0;i < listItemAdapter.balistItem.size();i++){ if(list.isItemChecked(i)){ list.setItemChecked(i,false); list.setItemChecked(i,false); }else { list.setItemChecked(i,true); } } setCountChange(); } }); del.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for(int i = 0;i < listItemAdapter.balistItem.size();i++){ if(list.isItemChecked(i)){ listItemAdapter.balistItem.remove(i); listItemAdapter.notifyDataSetChanged(); } } list.clearChoices(); setCountChange(); } }); } }
demo apk文件下载地址:https://files.cnblogs.com/files/zzerx/app-debug(1).apk