Android的ListView多選刪除Demo

練手做了個listview的多選demo,網上看其他人的例子感覺不是很難,自己動手做了下,各種細節問題,沒那麼簡單啊。既然做了,簡單寫個筆記記錄下。
練手demo,命名筆記亂,不要建議。
運行界面1
運行界面2

主界面佈局activity_main.xml

<RelativeLayout 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:id="@+id/rootView"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.listchecked.MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        >

    </ListView>

    <LinearLayout
        android:id="@+id/button_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/listView1"
        android:layout_alignParentBottom="true"
        android:orientation="vertical" >

        <Button
            android:id="@+id/del"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="刪除" />
    </LinearLayout>

</RelativeLayout>

列表item的佈局

<?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="match_parent"
    android:orientation="horizontal"
    android:descendantFocusability="blocksDescendants" >
<!--注意上面這個屬性,很關鍵,不加會導致list無法響應OnItemClickListener中的事件-->

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" 
       >

        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="false"
            android:focusable="false" />

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitCenter"
            android:src="@drawable/ic_launcher" />

    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/teacher"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Teacher" />

        <TextView
            android:id="@+id/time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Time" />

        <TextView
            android:id="@+id/peopleNum"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="peopleNum"
             />

    </LinearLayout>

</LinearLayout>

這個item的佈局就被在細節上坑了一次,item中添加button,checkbox,imageButton等時,會導致只響應這些控件的事件,item整體的事件就不會響應了,剛開始沒有加那條屬性,勾選checkbox後,點刪除沒有反應。這問題要發現也有點難度,之前見大神們推薦過分析佈局的工具hierarchyviewer,這個工具,個人感覺和前端開發中的F12類似啊,很方便,可以看到每個佈局的情況。也是好奇,點開一看,整個item的佈局,從父佈局,到子佈局,只要checkbox可以接受click,其他全部是false,這就是問題所在了,後來百度了一下,即如上結論。解決辦法就是添加
android:descendantFocusability=”blocksDescendants”
到list的item的佈局裏,添加以後,發現checkbox還是可以被單獨點擊,不響應list的點擊選中事件,很是奇怪,看其他人的例子中就沒有這種現象。最後只能設置checkbox不能被點擊
android:clickable=”false”
佈局問題解決了,下面是java類的源碼
首先是bean類,ItemBean.java

package com.example.listchecked;


public class ItemBean {
    private int imgRes;
    private String title,teacher,time;
    private int peopleNum,id;
    private boolean isChecked;
    private boolean isShow;

    public boolean isShow() {
        return isShow;
    }
    public void setShow(boolean isShow) {
        this.isShow = isShow;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public boolean isChecked() {
        return isChecked;
    }
    public void setChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }
    public int getImgRes() {
        return imgRes;
    }
    public void setImgRes(int img) {
        this.imgRes = img;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getTeacher() {
        return teacher;
    }
    public void setTeacher(String teacher) {
        this.teacher = teacher;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public int getPeopleNum() {
        return peopleNum;
    }
    public void setPeopleNum(int peopleNum) {
        this.peopleNum = peopleNum;
    }



}

自定義的Adapter,MyListAdapter.java

package com.example.listchecked;

import java.util.List;

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

public class MyListAdapter extends BaseAdapter
{
    private LayoutInflater inflater;
    private List<ItemBean> items;
    private ItemBean item;
    private OnShowItemClickListener onShowItemClickListener;

    public MyListAdapter(List<ItemBean> list,Context context)
    {
    items=list;
    inflater=LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
    // TODO 自動生成的方法存根
    return items.size();
    }

    @Override
    public Object getItem(int position) {
    // TODO 自動生成的方法存根
    return items.get(position);
    }

    @Override
    public long getItemId(int position) {
    // TODO 自動生成的方法存根
    return items.get(position).getId();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    // TODO 自動生成的方法存根
    ViewHolder holder;//使用ViewHolder,大神說能提升性能
    if(convertView==null)
    {
        holder=new ViewHolder();
        convertView=inflater.inflate(R.layout.item_view, null);
        holder.img=(ImageView) convertView.findViewById(R.id.imageView1);
        holder.cb=(CheckBox) convertView.findViewById(R.id.checkBox1);
        holder.title=(TextView)convertView.findViewById(R.id.title);
        holder.teacher=(TextView) convertView.findViewById(R.id.teacher);
        holder.time=(TextView) convertView.findViewById(R.id.time);
        holder.poeple=(TextView)convertView.findViewById(R.id.peopleNum);
        convertView.setTag(holder);
    }else
    {
       holder=(ViewHolder) convertView.getTag();
    }
    item=items.get(position);
    if(item.isShow())
    {
        holder.cb.setVisibility(View.VISIBLE);
    }
    else
    {
        holder.cb.setVisibility(View.GONE);
    }
    holder.img.setImageResource(item.getImgRes());
    holder.title.setText(item.getTitle());
    holder.teacher.setText("主講:"+item.getTeacher());
    holder.time.setText("課時:"+item.getTime()+"講");
    holder.poeple.setText("學習人數:"+item.getPeopleNum());

    holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {



        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(isChecked)
        {
            item.setChecked(true);
        }
        else
        {
            item.setChecked(false);
        }
        //回調方法,講item加入已選擇的
        onShowItemClickListener.onShowItemClick(item);
        }
    });
    //監聽後設置選擇狀態
    holder.cb.setChecked(item.isChecked());
    return convertView;
    }

    static class ViewHolder
    {
    ImageView img;
    CheckBox cb;
    TextView title,teacher,time,poeple;

    }

    public interface OnShowItemClickListener {
    public void onShowItemClick(ItemBean bean);
    }

    public void setOnShowItemClickListener(OnShowItemClickListener onShowItemClickListener) {
    this.onShowItemClickListener = onShowItemClickListener;
}
}

最後是MainActivity.java

package com.example.listchecked;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
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.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.example.listchecked.MyListAdapter.OnShowItemClickListener;

public class MainActivity extends Activity implements OnShowItemClickListener {

    private ListView listView;
    private List<ItemBean> dataList,selectedList;
    private MyListAdapter myAdapter;
    private RelativeLayout rootView;
    private LinearLayout menuView;
    private LinearLayout openView;
    private static boolean isShow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    isShow=false;
    setContentView(R.layout.activity_main);
    Button delbtn=(Button) findViewById(R.id.del);
    rootView=(RelativeLayout) findViewById(R.id.rootView);
    menuView=(LinearLayout) findViewById(R.id.button_group);
    listView=(ListView) findViewById(R.id.listView1);
    dataList=new ArrayList<ItemBean>();
    selectedList=new ArrayList<ItemBean>();
    for(int i=0;i<10;i++)
    {
        ItemBean item=new ItemBean();
        item.setId(i);
        item.setImgRes(R.drawable.ic_launcher);
        item.setTitle("第"+item.getId()+"個");
        item.setTeacher("楊老師");
        item.setTime("34");
        item.setPeopleNum(i+1*100);
        item.setChecked(false);
        item.setShow(isShow);
        dataList.add(item);
    }
    myAdapter=new MyListAdapter(dataList, this);
    myAdapter.setOnShowItemClickListener(MainActivity.this);
    listView.setAdapter(myAdapter);

    delbtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        // TODO 自動生成的方法存根
        showMenu();
        isShow=true;
        selectedList.clear();
        for(ItemBean item:dataList)
        {

            item.setShow(isShow);
        }
        myAdapter.notifyDataSetChanged();

        }
    });
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
        // TODO 自動生成的方法存根
        if (isShow) {
            ItemBean item = dataList.get(position);
            boolean isChecked = item.isChecked();
            if (isChecked) {
                item.setChecked(false);
            } else {
                item.setChecked(true);
            }
            myAdapter.notifyDataSetChanged();
            Log.d("select",selectedList.size()+"");
        }
        }
    });

    }
    //顯示選擇刪除等的菜單
    private void showMenu()
    {
    RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT);
    lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    openView=(LinearLayout) inflater.inflate(R.layout.delmenu_layout, null);
    rootView.removeView(menuView);
    rootView.addView(openView,lp);
    final Button sBtn=(Button) openView.findViewById(R.id.selectAll);
    Button dBtn=(Button) openView.findViewById(R.id.del_button);
    Button cBtn= (Button) openView.findViewById(R.id.cancel_button);
    sBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        // TODO 自動生成的方法存根
        if ("全選".equals(sBtn.getText().toString())) {
            for (ItemBean bean : dataList) {
                if (!bean.isChecked()) {
                    bean.setChecked(true);
                    if (!selectedList.contains(bean)) {
                        selectedList.add(bean);
                    }
                }
            }
            myAdapter.notifyDataSetChanged();
            sBtn.setText("反選");
        } else if ("反選".equals(sBtn.getText().toString())) {
            for (ItemBean bean : dataList) {
                bean.setChecked(false);
                if (!selectedList.contains(bean)) {
                    selectedList.remove(bean);
                }
            }
            myAdapter.notifyDataSetChanged();
            sBtn.setText("全選");
        }
        }
    });

    dBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        // TODO 自動生成的方法存根
        if (selectedList!=null && selectedList.size()>0) {
            dataList.removeAll(selectedList);
            myAdapter.notifyDataSetChanged();
            selectedList.clear();
        } else {
            Toast.makeText(MainActivity.this, "請選擇條目", Toast.LENGTH_SHORT).show();
        }
        }
    });
    cBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        // TODO 自動生成的方法存根
        if (isShow) {
            selectedList.clear();
            for (ItemBean bean : dataList) {
                bean.setChecked(false);
                bean.setShow(false);
            }
            myAdapter.notifyDataSetChanged();
            isShow = false;
            restoreView();
        }
        }
    });

    }
    @Override
    public void onShowItemClick(ItemBean bean) {
    // TODO 自動生成的方法存根
    if (bean.isChecked() && !selectedList.contains(bean)) {
        selectedList.add(bean);
    } else if (!bean.isChecked() && selectedList.contains(bean)) {
        selectedList.remove(bean);
    }
    }

    private void restoreView()
    {
    rootView.addView(menuView);
    if(openView!=null)
    {
        rootView.removeView(openView);
        openView=null;
    }

    }
}

最後還有那個小菜單的佈局,還是放上吧

<?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="match_parent"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/selectAll"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="全選" />

    <Button
        android:id="@+id/del_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="刪除" />

    <Button
        android:id="@+id/cancel_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="取消" />

</LinearLayout>

全部代碼都放上了,如果不想複製粘貼,GitHub地址:https://github.com/2767321434/ListChecked

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章