您的位置:首页 > 其它

带有CheckBox的ListView,实现删除和选中功能

2014-07-04 19:19 429 查看
Android实现带有CheckBox的ListView

[html] view
plaincopy

package com.zwq.umeng;

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.ImageView;

import android.widget.TextView;

public class MyAdapter extends BaseAdapter {

private LayoutInflater mInflater;

private List<Map<String, Object>> mData;

public static Map<Integer, Boolean> isSelected;

public MyAdapter(Context context) {

mInflater = LayoutInflater.from(context);

init();

}

//初始化

private void init() {

mData=new ArrayList<Map<String, Object>>();

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

Map<String, Object> map = new HashMap<String, Object>();

map.put("img", R.drawable.icon);

map.put("title", "第" + (i + 1) + "行的标题");

mData.add(map);

}

//这儿定义isSelected这个map是记录每个listitem的状态,初始状态全部为false。

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

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

isSelected.put(i, false);

}

}

@Override

public int getCount() {

return mData.size();

}

@Override

public Object getItem(int position) {

return null;

}

@Override

public long getItemId(int position) {

return 0;

}

@Override

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

ViewHolder holder = null;

//convertView为null的时候初始化convertView。

if (convertView == null) {

holder = new ViewHolder();

convertView = mInflater.inflate(R.layout.vlist, null);

holder.img = (ImageView) convertView.findViewById(R.id.img);

holder.title = (TextView) convertView.findViewById(R.id.title);

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

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

holder.img.setBackgroundResource((Integer) mData.get(position).get(

"img"));

holder.title.setText(mData.get(position).get("title").toString());

holder.cBox.setChecked(isSelected.get(position));

return convertView;

}

public final class ViewHolder {

public ImageView img;

public TextView title;

public CheckBox cBox;

}

}

项目要用到一个listview,要求是可以显示图片,后面还有有复选框。

先新建一个MyAdapter类,继承自BaseAdapter。在MyAdapter中实现对数据的绑定,我这儿由于是测试的,所以把数据写死了。

Java代码

上面类中要注意getView()方法中对数据的处理。

接下要新建一个list.xml文件,这个就是布局image、textview、checkbox。

[html] view
plaincopy

<TextView

android:id="@+id/title"

android:textSize="18dip"

android:layout_weight="1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

<CheckBox

android:id="@+id/cb"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:focusable="false"

android:focusableInTouchMode="false"

android:clickable="false"

android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>

</LinearLayout>

android:layout_weight="1"这一句可以使中间的textview权重增大,从而后面的checkbok可以居右显示。

[html] view
plaincopy

android:focusable="false"

android:focusableInTouchMode="false"

android:clickable="false"

这三句很重要,如果不加就会出现错误。

由于checkbox的点击事件优先级比listview的高,所以要在checkbox中添加android:focusable="false",使得checkbox初始的时候没有获取焦点。

接下来在main.xml中添加Listview组件

Java代码

[html] view
plaincopy

<ListView

android:id="@+id/lv"

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>

接下来就是在activity中调用:

Java代码

[html] view
plaincopy

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

MyAdapter adapter=new MyAdapter(this);

list.setAdapter(adapter);

list.setItemsCanFocus(false);

list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

list.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

ViewHolder vHollder = (ViewHolder) view.getTag();

//在每次获取点击的item时将对于的checkbox状态改变,同时修改map的值。

vHollder.cBox.toggle();

MyAdapter.isSelected.put(position, vHollder.cBox.isChecked());

}

});

最新看一下效果图:



要获取哪些项目被选择了,可以这样测试:

Java代码

[html] view
plaincopy

OnClickListener bPop = new OnClickListener() {

@Override

public void onClick(View v) {

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

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

ViewHolder vHollder = (ViewHolder) list.getChildAt(i).getTag();

Log.i(TAG, "--onClick --"+vHollder.title.getText());

}

}

}

};

总结

1、数据可以在Activity中获取,在初始化Adapter的时候当做参数传递过去,这样就可以是list编程动态的。

2、对MyAdapter中getview的理解不够,尤其是convertView.setTag(holder),

ListView结合Checkbox实现删除功能



效果图

实现要点:

1 Listview是一个动态的组件,实现监听Listview里的动作需要用到BaseAdapter类

2 数据存储结构ArrayList<HashMap<String, String>> list, 第一个string存放flag,用以判断是否选中;第二个string存放msg

3 一旦数据有变,必须使用mAdapter.notifyDataSetChanged(); 否则view无法得知数据变化,从而会报错

一共由以下文件组成(仅核心部分,参考慎用)

JAVA

[java] view
plaincopy





Button btnDelete;

ListView lv;

Context mContext;

MyListAdapter adapter;

private ArrayList<HashMap<String, String>> list;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_carton_no_main);

SysApplication.getInstance().addActivity(this);

btnDelete = (Button)findViewById(R.id.ctn_no_scan_delete_btn);

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

list = new ArrayList<HashMap<String, String>>();

mAdapter = new MyListAdapter(list, this);

lv.setAdapter(mAdapter);

//insert something

HashMap<String, String> map = new HashMap<String, String>();

map.put("content", 'test');

map.put("flag", "false");

list.add(map);

btnDelete.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Iterator<HashMap<String, String>> iterator = list.iterator();

while (iterator.hasNext()) {

HashMap<String, String> temp = iterator.next();

if (temp.get("flag").equals("true")) {

iterator.remove();

}

}

checkNum = 0;

//if you have changed list, please excute mAdapter.notifyDataSetChanged();

dataChanged();

}

});

lv.setOnItemClickListener(new OnItemClickListener() {

@Override

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

long arg3) {

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

holder.cb.toggle();

//store checkbox's status

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

list.get(arg2).put("flag", "true");

checkNum++;

} else {

list.get(arg2).put("flag", "false");

checkNum--;

}

}

});

}

public class MyListAdapter extends BaseAdapter{

private ArrayList<HashMap<String, String>> list;

private Context context;

private LayoutInflater inflater = null;

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

this.context = context;

this.list = list;

inflater = LayoutInflater.from(context);

}

@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) {

holder = new ViewHolder();

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

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

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

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

//init view

holder.tv.setText(list.get(position).get("content").toString());

holder.cb.setChecked(list.get(position).get("flag").equals("true"));

return convertView;

}

final class ViewHolder{

TextView tv;

CheckBox cb;

}

}

private void dataChanged(){

mAdapter.notifyDataSetChanged();

}

XML

1/2

[html] view
plaincopy





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

<LinearLayout xmlns:tools="http://schemas.android.com/tools"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@color/white"

android:orientation="vertical" >

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:descendantFocusability="blocksDescendants">

<CheckBox

android:id="@+id/carton_no_list_checked"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:clickable="false"

android:focusable="false"

android:focusableInTouchMode="false"

android:gravity="center_vertical" />

<TextView

android:id="@+id/carton_no_list_name"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginLeft="10dp"

android:layout_weight="1"

android:text="Name"

android:textColor="@color/viewfinder_mask"

android:textSize="20dp" />

</LinearLayout>

</LinearLayout>

2/2

[html] view
plaincopy





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

<LinearLayout xmlns:tools="http://schemas.android.com/tools"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/white"

android:orientation="vertical" >

<LinearLayout

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_weight="0.1">

<ListView

android:id="@+id/carton_no_list"

android:layout_width="match_parent"

android:layout_height="fill_parent"/>

</LinearLayout>

<LinearLayout

android:id="@+id/LinearLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_weight="0.7"

android:orientation="horizontal" >

<Button

android:id="@+id/ctn_no_scan_delete_btn"

android:layout_width="match_parent"

android:layout_height="50dp"

android:layout_weight="0.1"

android:text="Delete" />

</LinearLayout>

</LinearLayout>

同理,实现radiobox,也是一样的道理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐