android 隨手記 listview多選實現

天繼續和大傢分享涉及到listview的內容。在很多時候,我們會用到listview和checkbox配合來提供給用戶一些選擇操作。比如在一個清單頁面,我們需要記錄用戶勾選瞭哪些條目。這個的實現並不太難,但是有很多朋友來問我如何實現,他們有遇到各種各樣的問題,這裡就一並寫出來和大傢一起分享。

ListView的操作就一定會涉及到item和Adapter,我們還是先來實現這部分內容。

首先,寫個item的xml佈局,裡面放置一個TextView和一個CheckBox。要註意的時候,這裡我設置瞭CheckBox沒有焦點,這樣的話,無法單獨點擊checkbox,而是在點擊listview的條目後,Checkbox會響應操作。

[html]  

<?xml version="1.0" encoding="utf-8"?>  

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"  

    android:layout_width="fill_parent"  

    android:layout_height="fill_parent"  

    android:orientation="horizontal" >  

  

    <TextView  

        android:id="@+id/item_tv"  

        android:layout_width="0dp"  

        android:layout_height="wrap_content"  

        android:layout_weight="1"  

        android:gravity="center_vertical"  

         />  

  

    <CheckBox  

        android:id="@+id/item_cb"  

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content"  

        android:clickable="false"  

        android:focusable="false"  

        android:focusableInTouchMode="false"   

        android:gravity="center_vertical"  

        />  

  

</LinearLayout>  

 

下面就寫一個Adapter類,我們依然繼承BaseAdapter類。這裡我們使用一個HashMap<Integer,boolean>的鍵值來記錄checkbox在對應位置的選中狀況,這是本例的實現的基礎。

[java] 

package com.notice.listcheck;  

  

import java.util.ArrayList;  

import java.util.HashMap;  

  

import android.content.Context;  

import android.view.LayoutInflater;  

import android.view.View;  

import android.view.ViewGroup;  

import android.widget.BaseAdapter;  

import android.widget.CheckBox;  

import android.widget.TextView;  

  

public class MyAdapter extends BaseAdapter{  

    // 填充數據的list  

    private ArrayList<String> list;  

    // 用來控制CheckBox的選中狀況  

    private static HashMap<Integer,Boolean> isSelected;  

    // 上下文  

    private Context context;  

    // 用來導入佈局  

    private LayoutInflater inflater = null;  

      

    // 構造器  

    public MyAdapter(ArrayList<String> list, Context context) {  

        this.context = context;  

        this.list = list;  

        inflater = LayoutInflater.from(context);  

        isSelected = new HashMap<Integer, Boolean>();  

        // 初始化數據  

        initDate();  

    }  

  

    // 初始化isSelected的數據  

    private void initDate(){  

        for(int i=0; i<list.size();i++) {  

            getIsSelected().put(i,false);  

        }  

    }  

  

    @Override  

    public int getCount() {  

        return list.size();  

    }  

  

    @Override  

    public Object getItem(int position) {  

        return list.get(position);  

    }  

  

    @Override  

    public long getItemId(int position) {  

        return position;  

    }  

  

    @Override  

    public View getView(int position, View convertView, ViewGroup parent) {  

        ViewHolder holder = null;  

            if (convertView == null) {  

            // 獲得ViewHolder對象  

            holder = new ViewHolder();  

                // 導入佈局並賦值給convertview  

                convertView = inflater.inflate(R.layout.listviewitem, null);  

            holder.tv = (TextView) convertView.findViewById(R.id.item_tv);  

            holder.cb = (CheckBox) convertView.findViewById(R.id.item_cb);  

            // 為view設置標簽  

            convertView.setTag(holder);  

        } else {  

            // 取出holder  

            holder = (ViewHolder) convertView.getTag();  

            }  

  

  

        // 設置list中TextView的顯示  

        holder.tv.setText(list.get(position));  

        // 根據isSelected來設置checkbox的選中狀況  

        holder.cb.setChecked(getIsSelected().get(position));  

        return convertView;  

    }  

  

    public static HashMap<Integer,Boolean> getIsSelected() {  

        return isSelected;  

    }  

  

    public static void setIsSelected(HashMap<Integer,Boolean> isSelected) {  

        MyAdapter.isSelected = isSelected;  

    }  

  

}  

 

 

註釋已經寫的非常詳盡瞭,通過

holder.cb.setChecked(getIsSelected().get(position));

這行代碼我們實現瞭設置CheckBox的選中狀況。

那麼我們隻需要在點擊事件中,控制isSelected的鍵值即可控制對應位置checkbox的選中瞭。

在Activity中我們除瞭放置一個ListView外,還放置瞭三個按鈕,分別實現全選,取消和反選。

看下Activity類的代碼:

[java] 

package com.notice.listcheck;  

  

import java.util.ArrayList;  

  

import android.app.Activity;  

import android.os.Bundle;  

import android.view.View;  

import android.view.View.OnClickListener;  

import android.widget.AdapterView;  

import android.widget.AdapterView.OnItemClickListener;  

import android.widget.Button;  

import android.widget.ListView;  

import android.widget.TextView;  

  

public class Ex_checkboxActivity extends Activity {  

      

    private ListView lv;  

    private MyAdapter mAdapter;  

    private ArrayList<String> list;  

    private Button bt_selectall;  

    private Button bt_cancel;  

    private Button bt_deselectall;  

    private int checkNum; // 記錄選中的條目數量  

    private TextView tv_show;// 用於顯示選中的條目數量  

      

    /** Called when the activity is first created. */  

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

        /* 實例化各個控件 */  

        lv = (ListView) findViewById(R.id.lv);  

        bt_selectall = (Button) findViewById(R.id.bt_selectall);  

        bt_cancel = (Button) findViewById(R.id.bt_cancelselectall);  

        bt_deselectall = (Button) findViewById(R.id.bt_deselectall);  

        tv_show = (TextView) findViewById(R.id.tv);  

        list = new ArrayList<String>();  

        // 為Adapter準備數據  

        initDate();  

        // 實例化自定義的MyAdapter  

        mAdapter = new MyAdapter(list, this);  

        // 綁定Adapter  

        lv.setAdapter(mAdapter);  

  

        // 全選按鈕的回調接口  

        bt_selectall.setOnClickListener(new OnClickListener() {  

  

            @Override  

            public void onClick(View v) {  

                // 遍歷list的長度,將MyAdapter中的map值全部設為true  

                for (int i = 0; i < list.size(); i++) {  

                    MyAdapter.getIsSelected().put(i, true);  

                }  

                // 數量設為list的長度  

                checkNum = list.size();  

                // 刷新listview和TextView的顯示  

                dataChanged();  

  

            }  

        });  

        // 取消按鈕的回調接口  

        bt_cancel.setOnClickListener(new OnClickListener() {  

  

            @Override  

            public void onClick(View v) {  

                // 遍歷list的長度,將已選的按鈕設為未選  

                for (int i = 0; i < list.size(); i++) {  

                    if (MyAdapter.getIsSelected().get(i)) {  

                        MyAdapter.getIsSelected().put(i, false);  

                        checkNum–;// 數量減1  

                    }  

                }  

                // 刷新listview和TextView的顯示  

                dataChanged();  

  

            }  

        });  

  

        // 反選按鈕的回調接口  

        bt_deselectall.setOnClickListener(new OnClickListener() {  

  

            @Override  

            public void onClick(View v) {  

                // 遍歷list的長度,將已選的設為未選,未選的設為已選  

                for (int i = 0; i < list.size(); i++) {  

                    if (MyAdapter.getIsSelected().get(i)) {  

                        MyAdapter.getIsSelected().put(i, false);  

                        checkNum–;  

                    } else {  

                        MyAdapter.getIsSelected().put(i, true);  

                        checkNum++;  

                    }  

  

                }  

                // 刷新listview和TextView的顯示  

                dataChanged();  

            }  

        });  

          

        // 綁定listView的監聽器  

        lv.setOnItemClickListener(new OnItemClickListener() {  

  

            @Override  

            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  

                    long arg3) {  

                // 取得ViewHolder對象,這樣就省去瞭通過層層的findViewById去實例化我們需要的cb實例的步驟  

          ViewHolder holder = (ViewHolder) arg1.getTag();  

                // 改變CheckBox的狀態  

                holder.cb.toggle();  

                // 將CheckBox的選中狀況記錄下來  

                MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked());   

                // 調整選定條目  

                if (holder.cb.isChecked() == true) {  

                    checkNum++;  

                } else {  

                    checkNum–;  

                }  

                // 用TextView顯示  

                tv_show.setText("已選中"+checkNum+"項");  

                  

            }  

        });  

    }  

  

    // 初始化數據  

    private void initDate() {  

        for (int i = 0; i < 15; i++) {  

            list.add("data" + "   " + i);  

        }  

    }  

  

    // 刷新listview和TextView的顯示  

    private void dataChanged() {  

        // 通知listView刷新  

        mAdapter.notifyDataSetChanged();  

        // TextView顯示最新的選中數目  

        tv_show.setText("已選中" + checkNum + "項");  

    }  

  

      

}  

 

 

發佈留言