Android ListView的批量處理(多選/反選/刪除)

在Android開發中常常遇到使用ListView的狀況,有時候須要的不單單是列表顯示,還有長按列表進行多選,而且批量刪除的狀況,在這裏記錄一下本身的所學。

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

相關文章
相關標籤/搜索