教你如何解决ListView+CheckBox的冲突
ListView是我们每个Android应用app比不可少的一部分,通常它以列表形式用来展示大数据,在展示时有肯能配合Checkbox来使用,列如:购物车当ListView与CheckBox同时使用的时候可能就会产生一些冲突达不到你期望的效果,一般就会出现一下情况?
焦点冲突
- 点击事件冲突
- 选中的状态无法保存
- ListView滚动时之前保存的状态发生改变
那么产生的原因:主要是ListView的适配器中的getView()方法重复调用,当我们滚动ListView,当之前保存的Item不可见时会移除掉Item的状态解决方案:通过LinkedHashMap这种简直对的方式来保存,通过LinkedHashMap的key于position关联来保存当前Item的状态。问题我们就分析到这至于对不对我们用代码验证,为了简单我用ImageView代替了ChekBox;首先给大家看几张效果图.
图片弄得比较丑,咱们忽略不计,等会提供源码连接
1 /** 2 * 商品实体类 3 * @author joe.xiang 4 */ 5 public class ShoppingModel { 6 public String pname; 7 public int prices; 8 public int pimage; 9 //是否选中标识 10 public boolean ischecked=false; 11 public ShoppingModel(String pname, int prices, int pimage,boolean ischecked) { 12 super(); 13 this.pname = pname; 14 this.prices = prices; 15 this.pimage = pimage; 16 this.ischecked = ischecked; 17 } 18 public boolean isIschecked() { 19 return ischecked; 20 } 21 public void setIschecked(boolean ischecked) { 22 this.ischecked = ischecked; 23 } 24 } 25 26 27 28 package com.example.listviewandroidcheckbox.activity; 29 import java.util.ArrayList; 30 import java.util.LinkedHashMap; 31 import java.util.List; 32 import com.example.listviewandroidcheckbox.R; 33 import com.example.listviewandroidcheckbox.adapter.ListCheckboxAdapter; 34 import com.example.listviewandroidcheckbox.model.ShoppingModel; 35 import android.app.Activity; 36 import android.os.Bundle; 37 import android.util.Log; 38 import android.view.View; 39 import android.view.View.OnClickListener; 40 import android.widget.Button; 41 import android.widget.CheckBox; 42 import android.widget.ListView; 43 import android.widget.TextView; 44 import android.widget.Toast; 45 /** 46 * 此案列主要是解决ListView和Checkbox的冲突 47 * @author joe.xiang 48 */ 49 public class ListViewAndCheckboxActivity extends Activity implements OnClickListener 50 { 51 private static final String TAG="ListViewAndCheckboxActivity"; 52 private TextView checknumber; 53 private ListView listveiw; 54 private CheckBox allselected; 55 private Button sumnumber; 56 private Button deleted; 57 //保存商品信息 58 private List<ShoppingModel> listShops; 59 //保存选中的商品信息 60 private List<ShoppingModel> NewlistShops; 61 //绑定数据 62 private ListCheckboxAdapter adapter; 63 //true 选中 false 未选中 64 public static boolean mflag; 65 //默认不选中 66 private int number = 0; 67 //总价格 68 private int sumprices; 69 70 @Override 71 protected void onCreate(Bundle savedInstanceState) { 72 super.onCreate(savedInstanceState); 73 setContentView(R.layout.activity_main); 74 initview(); 75 } 76 77 /** 78 * 初始化布局控件 79 */ 80 public void initview(){ 81 checknumber = (TextView) findViewById(R.id.checknumber); 82 listveiw = (ListView) findViewById(R.id.listveiw); 83 allselected = (CheckBox) findViewById(R.id.allselected); 84 sumnumber = (Button) findViewById(R.id.sumnumber); 85 deleted = (Button) findViewById(R.id.deleted); 86 allselected.setOnClickListener(this); 87 sumnumber.setOnClickListener(this); 88 deleted.setOnClickListener(this); 89 checknumber.setText("你选中了" + number + "个"); 90 listShops = getShopData(); 91 adapter = new ListCheckboxAdapter(this,checknumber); 92 adapter.setData(listShops, mflag); 93 listveiw.setAdapter(adapter); 94 } 95 96 /** 97 * 获取商品数据(网络数据) 98 * @return 99 */ 100 public List<ShoppingModel> getShopData(){ 101 listShops = new ArrayList<ShoppingModel>(); 102 for (int i = 0; i < 60; i++) { 103 listShops.add(new ShoppingModel("美女"+i, 100, R.drawable.appmain_subject_1,mflag)); 104 } 105 return listShops; 106 } 107 108 109 @Override 110 public void onClick(View v) { 111 switch (v.getId()) { 112 //全选、反选 113 case R.id.allselected: 114 String allseted = allselected.getText().toString().trim(); 115 if(allseted.equals("全选")){ 116 mflag = true; 117 adapter.setData(listShops, mflag); 118 allselected.setText("反选"); 119 checknumber.setText("你选中了" + listShops.size() + "个"); 120 }else{ 121 mflag = false; 122 adapter.setData(listShops, mflag); 123 allselected.setText("全选"); 124 checknumber.setText("你选中了" + number+ "个"); 125 } 126 break; 127 //删除选中 128 case R.id.deleted: 129 listShops = bianzhi2(); 130 adapter.setData(listShops, mflag); 131 checknumber.setText("你选中了" + number + "个"); 132 break; 133 //计算选中的价格 134 case R.id.sumnumber: 135 for (ShoppingModel sml : listShops) { 136 if(sml.isIschecked()){ 137 sumprices+=sml.prices; 138 } 139 } 140 ShowToast("总价为" + sumprices); 141 sumprices = 0; 142 break; 143 } 144 } 145 146 147 148 //获取你选中的商品信息 149 public List<ShoppingModel> bianzhi2() { 150 ShoppingModel kvalues =null; 151 NewlistShops = new ArrayList<ShoppingModel>(); 152 LinkedHashMap<Integer, ShoppingModel> listmap = adapter.shopmap; 153 for (Integer key : listmap.keySet()) { 154 kvalues = listmap.get(key); 155 NewlistShops.add(kvalues); 156 } 157 LogUtil(NewlistShops.size()+"全选大小"); 158 listShops.removeAll(NewlistShops); 159 adapter.shopmap.clear(); 160 return listShops; 161 } 162 163 public void LogUtil(String mesglog){ 164 Log.i(mesglog, TAG); 165 } 166 public void ShowToast(String mesglog){ 167 Toast.makeText(ListViewAndCheckboxActivity.this,mesglog, 1).show(); 168 } 169 } 170 171 package com.example.listviewandroidcheckbox.adapter; 172 import java.util.LinkedHashMap; 173 import java.util.List; 174 import com.example.listviewandroidcheckbox.R; 175 import com.example.listviewandroidcheckbox.model.ShoppingModel; 176 import android.content.Context; 177 import android.view.LayoutInflater; 178 import android.view.View; 179 import android.view.View.OnClickListener; 180 import android.view.ViewGroup; 181 import android.widget.BaseAdapter; 182 import android.widget.CheckBox; 183 import android.widget.ImageView; 184 import android.widget.TextView; 185 186 187 public class ListCheckboxAdapter extends BaseAdapter { 188 public Context mContext; 189 public TextView numberview; 190 public CheckBox allselected; 191 public LayoutInflater mInflater; 192 public List<ShoppingModel> listShop ; 193 public static boolean mflag; 194 public static LinkedHashMap<Integer,ShoppingModel> shopmap = new LinkedHashMap<Integer, ShoppingModel>(); 195 196 public ListCheckboxAdapter(Context context,TextView checknumber) { 197 this.mContext = context; 198 this.numberview = checknumber; 199 mInflater = LayoutInflater.from(mContext); 200 } 201 202 public void setData(List<ShoppingModel> listShops,boolean flag){ 203 this.listShop = listShops; 204 for (int i = 0; i < listShop.size(); i++) { 205 listShop.get(i).setIschecked(flag); 206 } 207 notifyDataSetChanged(); 208 } 209 210 211 @Override 212 public int getCount() { 213 return listShop.size(); 214 } 215 216 @Override 217 public Object getItem(int position) { 218 return listShop.get(position); 219 } 220 221 @Override 222 public long getItemId(int position) { 223 return position; 224 } 225 226 @Override 227 public View getView(final int position, View convertView, ViewGroup parent) { 228 final ViewHolder holder ; 229 if(convertView==null){ 230 convertView = mInflater.inflate(R.layout.list_item, null); 231 holder = new ViewHolder(); 232 holder.imageview = (ImageView) convertView.findViewById(R.id.pimage); 233 holder.textview = (TextView) convertView.findViewById(R.id.pname); 234 holder.ptextview = (TextView) convertView.findViewById(R.id.prices); 235 holder.stateimageview = (ImageView) convertView.findViewById(R.id.pstate); 236 convertView.setTag(holder); 237 }else{ 238 holder = (ViewHolder) convertView.getTag(); 239 } 240 if(listShop.get(position).isIschecked()){ 241 holder.stateimageview.setImageResource(R.drawable.es_5); 242 }else{ 243 holder.stateimageview.setImageResource(R.drawable.es_6); 244 } 245 holder.imageview.setImageResource(listShop.get(position).pimage); 246 holder.textview.setText(listShop.get(position).pname.toString()); 247 holder.ptextview.setText(listShop.get(position).prices + ""); 248 249 holder.stateimageview.setOnClickListener(new OnClickListener() { 250 @Override 251 public void onClick(View v) { 252 if(listShop.get(position).isIschecked()){ 253 listShop.get(position).setIschecked(false); 254 shopmap.remove(position); 255 holder.stateimageview.setImageResource(R.drawable.es_6); 256 numberview.setText("你选中了" + shopmap.size() + "个"); 257 }else { 258 listShop.get(position).setIschecked(true); 259 shopmap.put(position, listShop.get(position)); 260 holder.stateimageview.setImageResource(R.drawable.es_5); 261 numberview.setText("你选中了" + shopmap.size() + "个"); 262 } 263 } 264 }); 265 return convertView; 266 } 267 268 static class ViewHolder{ 269 ImageView imageview; 270 TextView textview; 271 TextView ptextview; 272 ImageView stateimageview; 273 } 274 }
代码里面注释的比较详细,我就不仔细详讲了,最后祝大家新年快乐。
源码连接:http://i.cnblogs.com/Files.aspx