先上效果圖:
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