Android高級控件(一)——ListView綁定CheckBox實現全選,添加和刪除等功能


Android高級控件(一)——ListView綁定CheckBox實現全選,添加和刪除等功能


這個控件還是挺復雜的。也是項目中應該算是比較經常使用的了,所以寫了一個小Demo來講講,主要是自己定義adapter的使用方法。加了非常多的推斷等等等等….我們先來看看實現的效果吧!

這里寫圖片描寫敘述

好的,我們新建一個項目LvCheckBox

這里寫圖片描寫敘述

我們事先先把這兩個布局寫好吧,一個是主布局,另一個listview的item.xml。相信不用多說

activity_main.xml

<LinearLayout 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:orientation="vertical" >

    <RelativeLayout  android:layout_width="match_parent" android:layout_height="50dp" android:background="#238286" >

        <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="ListView綁定CheckBox" android:textColor="#fff" />

        <TextView  android:id="@+id/tv_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="17dp" android:text="添加" android:textColor="#fff" />
    </RelativeLayout>

    <ListView  android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" >
    </ListView>

    <LinearLayout  android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" >

        <Button  android:id="@+id/btn_detele" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginRight="1dp" android:layout_weight="1" android:background="#238286" android:text="刪除" android:textColor="#fff" />

        <Button  android:id="@+id/btn_select_all" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="1dp" android:layout_weight="1" android:background="#238286" android:text="全選" android:textColor="#fff" />
    </LinearLayout>

</LinearLayout>

item.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="50dp" android:gravity="center_vertical" android:orientation="horizontal" >

    <TextView  android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_weight="7" android:text="text" />

    <CheckBox  android:id="@+id/cbCheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" />

</LinearLayout>

item.xml僅僅有兩個控件。非常好理解吧

初始化控件

我們用initView()方法來初始化這些控件
    private void initView() {
        tv_add = (TextView) findViewById(R.id.tv_add);
        tv_add.setOnClickListener(this);
        btn_detele = (Button) findViewById(R.id.btn_detele);
        btn_detele.setOnClickListener(this);
        btn_select_all = (Button) findViewById(R.id.btn_select_all);
        btn_select_all.setOnClickListener(this);
        listview = (ListView) findViewById(R.id.listview);

    }

然后繼承點擊事件,button的和listview的

implements OnClickListener,OnItemClickListener

自己定義Adapter

這里最難的就是adapter了

1.Bean

我們為了數據的記錄方便。我們提前寫一個實體類
package com.lgl.lvcheckbox;

public class Bean {

    private String title;

    // 構造方法
    public Bean(String title) {
        super();
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

ListAdapter

這里全部的都寫了凝視,也方便大家看清
package com.lgl.lvcheckbox;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

/** * 自己定義適配器 * * @author LGL * */
public class ListAdapter extends BaseAdapter {

    // 數據集
    private List<Bean> list = new ArrayList<Bean>();
    // 上下文
    private Context mContext;
    // 存儲勾選框狀態的map集合
    private Map<Integer, Boolean> isCheck = new HashMap<Integer, Boolean>();

    // 構造方法
    public ListAdapter(Context mContext) {
        super();
        this.mContext = mContext;
        // 默覺得不選中
        initCheck(false);
    }

    // 初始化map集合
    public void initCheck(boolean flag) {
        // map集合的數量和list的數量是一致的
        for (int i = 0; i < list.size(); i++) {
            // 設置默認的顯示
            isCheck.put(i, flag);
        }
    }

    // 設置數據
    public void setData(List<Bean> data) {
        this.list = data;
    }

    // 加入數據
    public void addData(Bean bean) {
        // 下標 數據
        list.add(0, bean);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        // 假設為null就返回一個0
        return list != null ? list.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        View view = null;
        // 推斷是不是第一次進來
        if (convertView == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.title = (TextView) view.findViewById(R.id.tvTitle);
            viewHolder.cbCheckBox = (CheckBox) view
                    .findViewById(R.id.cbCheckBox);
            // 標記,能夠復用
            view.setTag(viewHolder);
        } else {
            view = convertView;
            // 直接拿過來用
            viewHolder = (ViewHolder) view.getTag();
        }
        // 拿到對象
        Bean bean = list.get(position);
        // 填充數據
        viewHolder.title.setText(bean.getTitle().toString());
        // 勾選框的點擊事件
        viewHolder.cbCheckBox
                .setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {
                        // 用map集合保存
                        isCheck.put(position, isChecked);
                    }
                });
        // 設置狀態
        if (isCheck.get(position) == null) {
            isCheck.put(position, false);
        }
        viewHolder.cbCheckBox.setChecked(isCheck.get(position));
        return view;
    }

    // 優化
    public static class ViewHolder {
        public TextView title;
        public CheckBox cbCheckBox;
    }

    // 全選button獲取狀態
    public Map<Integer, Boolean> getMap() {
        // 返回狀態
        return isCheck;
    }

    // 刪除一個數據
    public void removeData(int position) {
        list.remove(position);
    }
}

當然,有些方法是后面寫的,我們提前寫好。比方刪除和添加什么的

初始化數據

我們默認總是須要點數據的
    private void initData() {
        // 默認顯示的數據
        List<Bean> list = new ArrayList<Bean>();
        list.add(new Bean("張三"));
        list.add(new Bean("李四"));
        list.add(new Bean("王五"));

        adapter = new ListAdapter(this);
        adapter.setData(list);
        listview.setAdapter(adapter);
    }

添加數據

    // 加入數據
        case R.id.tv_add:
            adapter.addData(new Bean("劉桂林"));
            // 通知刷新適配器
            adapter.notifyDataSetChanged();
            break;

全選數據

當我們全選的時候,button應該為全不選的,所以這里我們這里有狀態的
    case R.id.btn_select_all:
            // 全選——全不選
            Map<Integer, Boolean> isCheck = adapter.getMap();
            if (btn_select_all.getText().equals("全選")) {
                adapter.initCheck(true);
                // 通知刷新適配器
                adapter.notifyDataSetChanged();
                btn_select_all.setText("全不選");
                btn_select_all.setTextColor(Color.YELLOW);
            } else if (btn_select_all.getText().equals("全不選")) {
                adapter.initCheck(false);
                // 通知刷新適配器
                adapter.notifyDataSetChanged();
                btn_select_all.setText("全選");
                btn_select_all.setTextColor(Color.YELLOW);
            }
            break;

刪除數據

刪除也是要考慮非常多因素
// 刪除數據
        case R.id.btn_detele:
            // 拿到全部數據
            Map<Integer, Boolean> isCheck_delete = adapter.getMap();
            // 獲取到條目數量。map.size = list.size,所以
            int count = adapter.getCount();
            // 遍歷
            for (int i = 0; i < count; i++) {
                // 刪除有兩個map和list都要刪除 ,計算方式
                int position = i - (count - adapter.getCount());
                // 推斷狀態 true為刪除
                if (isCheck_delete.get(i) != null && isCheck_delete.get(i)) {
                    // listview刪除數據
                    isCheck_delete.remove(i);
                    adapter.removeData(position);
                }
            }
            btn_select_all.setText("全選");
            btn_select_all.setTextColor(Color.WHITE);
            adapter.notifyDataSetChanged();
            break;

這里的

int position = i - (count - adapter.getCount());

是一個計算方式。當我們刪除之后。實際上數組是須要又一次排列的,同一時候button也要變回全選狀態的

這里寫圖片描寫敘述

listview的點擊

我們直接點擊也是能夠勾選cheakbox選中的
// listview的點擊事件
    @Override
    public void onItemClick(AdapterView<?

> parent, View view, int position, long id) { // 推斷view是否同樣 if (view.getTag() instanceof ViewHolder) { // 假設是的話。重用 ViewHolder holder = (ViewHolder) view.getTag(); // 自己主動觸發 holder.cbCheckBox.toggle(); } }

好的,這種話就能夠實現了,假設不懂的話能夠下載本文demo參考。覺得好的點個贊

Demo下載地址:http://download.csdn.net/detail/qq_26787115/9423306


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM