如何解决ListView与CheckBox的冲突问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决ListView与CheckBox的冲突问题相关的知识,希望对你有一定的参考价值。
ListView是我们每个android应用app比不可少的一部分,通常它以列表形式用来展示大数据,在展示时有肯能配合Checkbox来使用,列如:购物车当ListView与CheckBox同时使用的时候可能就会产生一些冲突达不到你期望的效果,一般就会出现一下情况?
- 焦点冲突
- 点击事件冲突
- 选中的状态无法保存
- ListView滚动时之前保存的状态发生改变
那么产生的原因:主要是ListView的适配器中的getView()方法重复调用,当我们滚动ListView,当之前保存的Item不可见时会移除掉Item的状态解决方案:通过LinkedHashMap这种简直对的方式来保存,通过LinkedHashMap的key于position关联来保存当前Item的状态。问题我们就分析到这至于对不对我们用代码验证,为了简单我用ImageView代替了ChekBox;首先给大家看几张效果图.
图片弄得比较丑,咱们忽略不计,等会提供源码连接
/** * 商品实体类 * @author joe.xiang */ public class ShoppingModel { public String pname; public int prices; public int pimage; //是否选中标识 public boolean ischecked=false; public ShoppingModel(String pname, int prices, int pimage,boolean ischecked) { super(); this.pname = pname; this.prices = prices; this.pimage = pimage; this.ischecked = ischecked; } public boolean isIschecked() { return ischecked; } public void setIschecked(boolean ischecked) { this.ischecked = ischecked; } } package com.example.listviewandroidcheckbox.activity; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import com.example.listviewandroidcheckbox.R; import com.example.listviewandroidcheckbox.adapter.ListCheckboxAdapter; import com.example.listviewandroidcheckbox.model.ShoppingModel; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; /** * 此案列主要是解决ListView和Checkbox的冲突 * @author joe.xiang */ public class ListViewAndCheckboxActivity extends Activity implements OnClickListener { private static final String TAG="ListViewAndCheckboxActivity"; private TextView checknumber; private ListView listveiw; private CheckBox allselected; private Button sumnumber; private Button deleted; //保存商品信息 private List<ShoppingModel> listShops; //保存选中的商品信息 private List<ShoppingModel> NewlistShops; //绑定数据 private ListCheckboxAdapter adapter; //true 选中 false 未选中 public static boolean mflag; //默认不选中 private int number = 0; //总价格 private int sumprices; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initview(); } /** * 初始化布局控件 */ public void initview(){ checknumber = (TextView) findViewById(R.id.checknumber); listveiw = (ListView) findViewById(R.id.listveiw); allselected = (CheckBox) findViewById(R.id.allselected); sumnumber = (Button) findViewById(R.id.sumnumber); deleted = (Button) findViewById(R.id.deleted); allselected.setOnClickListener(this); sumnumber.setOnClickListener(this); deleted.setOnClickListener(this); checknumber.setText("你选中了" + number + "个"); listShops = getShopData(); adapter = new ListCheckboxAdapter(this,checknumber); adapter.setData(listShops, mflag); listveiw.setAdapter(adapter); } /** * 获取商品数据(网络数据) * @return */ public List<ShoppingModel> getShopData(){ listShops = new ArrayList<ShoppingModel>(); for (int i = 0; i < 60; i++) { listShops.add(new ShoppingModel("美女"+i, 100, R.drawable.appmain_subject_1,mflag)); } return listShops; } @Override public void onClick(View v) { switch (v.getId()) { //全选、反选 case R.id.allselected: String allseted = allselected.getText().toString().trim(); if(allseted.equals("全选")){ mflag = true; adapter.setData(listShops, mflag); allselected.setText("反选"); checknumber.setText("你选中了" + listShops.size() + "个"); }else{ mflag = false; adapter.setData(listShops, mflag); allselected.setText("全选"); checknumber.setText("你选中了" + number+ "个"); } break; //删除选中 case R.id.deleted: listShops = bianzhi2(); adapter.setData(listShops, mflag); checknumber.setText("你选中了" + number + "个"); break; //计算选中的价格 case R.id.sumnumber: for (ShoppingModel sml : listShops) { if(sml.isIschecked()){ sumprices+=sml.prices; } } ShowToast("总价为" + sumprices); sumprices = 0; break; } } //获取你选中的商品信息 public List<ShoppingModel> bianzhi2() { ShoppingModel kvalues =null; NewlistShops = new ArrayList<ShoppingModel>(); LinkedHashMap<Integer, ShoppingModel> listmap = adapter.shopmap; for (Integer key : listmap.keySet()) { kvalues = listmap.get(key); NewlistShops.add(kvalues); } LogUtil(NewlistShops.size()+"全选大小"); listShops.removeAll(NewlistShops); adapter.shopmap.clear(); return listShops; } public void LogUtil(String mesglog){ Log.i(mesglog, TAG); } public void ShowToast(String mesglog){ Toast.makeText(ListViewAndCheckboxActivity.this,mesglog, 1).show(); } } package com.example.listviewandroidcheckbox.adapter; import java.util.LinkedHashMap; import java.util.List; import com.example.listviewandroidcheckbox.R; import com.example.listviewandroidcheckbox.model.ShoppingModel; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; public class ListCheckboxAdapter extends BaseAdapter { public Context mContext; public TextView numberview; public CheckBox allselected; public LayoutInflater mInflater; public List<ShoppingModel> listShop ; public static boolean mflag; public static LinkedHashMap<Integer,ShoppingModel> shopmap = new LinkedHashMap<Integer, ShoppingModel>(); public ListCheckboxAdapter(Context context,TextView checknumber) { this.mContext = context; this.numberview = checknumber; mInflater = LayoutInflater.from(mContext); } public void setData(List<ShoppingModel> listShops,boolean flag){ this.listShop = listShops; for (int i = 0; i < listShop.size(); i++) { listShop.get(i).setIschecked(flag); } notifyDataSetChanged(); } @Override public int getCount() { return listShop.size(); } @Override public Object getItem(int position) { return listShop.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder ; if(convertView==null){ convertView = mInflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.imageview = (ImageView) convertView.findViewById(R.id.pimage); holder.textview = (TextView) convertView.findViewById(R.id.pname); holder.ptextview = (TextView) convertView.findViewById(R.id.prices); holder.stateimageview = (ImageView) convertView.findViewById(R.id.pstate); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } if(listShop.get(position).isIschecked()){ holder.stateimageview.setImageResource(R.drawable.es_5); }else{ holder.stateimageview.setImageResource(R.drawable.es_6); } holder.imageview.setImageResource(listShop.get(position).pimage); holder.textview.setText(listShop.get(position).pname.toString()); holder.ptextview.setText(listShop.get(position).prices + ""); holder.stateimageview.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(listShop.get(position).isIschecked()){ listShop.get(position).setIschecked(false); shopmap.remove(position); holder.stateimageview.setImageResource(R.drawable.es_6); numberview.setText("你选中了" + shopmap.size() + "个"); }else { listShop.get(position).setIschecked(true); shopmap.put(position, listShop.get(position)); holder.stateimageview.setImageResource(R.drawable.es_5); numberview.setText("你选中了" + shopmap.size() + "个"); } } }); return convertView; } static class ViewHolder{ ImageView imageview; TextView textview; TextView ptextview; ImageView stateimageview; } }
代码里面注释的比较详细,我就不仔细详讲了,最后祝大家新年快乐。
以上是关于如何解决ListView与CheckBox的冲突问题的主要内容,如果未能解决你的问题,请参考以下文章
完美解决ListView和CheckBox焦点冲突及复用时CheckBox错位等一系列问题
Android学习笔记之ListView与Item的焦点冲突处理