如何解决ListView与CheckBox的冲突问题

ListView是我们每个Android应用app比不可少的一部分,通常它以列表形式用来展示大数据,在展示时有肯能配合Checkbox来使用,列如:购物车当ListView与CheckBox同时使用的时候可能就会产生一些冲突达不到你期望的效果,一般就会出现一下情况?

  1. 焦点冲突
  2. 点击事件冲突
  3. 选中的状态无法保存
  4. 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;
    }
}

代码里面注释的比较详细,我就不仔细详讲了,最后祝大家新年快乐。


				
时间: 2024-10-11 23:51:59

如何解决ListView与CheckBox的冲突问题的相关文章

android解决listview与scrollview的冲突、自定义listview的高度以及上下拉刷新

     很多时候我们需要使用listview与嵌套使用,那么问题来了,listview里面自带了 滚动条,而又嵌套在scrollview里面.所以引发了一系列的冲突.listview显示不全. 今天给出一个全新的上下拉刷新与解决冲突的方案. .点击下载下拉刷新上拉加载工具      下载完工具后我们复制粘贴到我们自己的工程里面,使用方式和自定义view一样. 下面贴出代码 看到代码贴如也就这么回事.但是我们注意了,这个时候的listview是包裹在scroll里面的.那么滚动起来肯定不行的..

使用LinearLayout实现ListView,解决ListView和ScrollView滚动冲突

在项目中,我们常常会遇到一个ScrollView里面会嵌套ListView的情况,但往往你会发现,ListView和ScrollView的滚动时间会有冲突问题,造成ListView不能完全显示.虽然网上有给出解决方案,但事实上并不好用,并不完美. public void setListViewHeightBasedOnChildren(ListView listView) { // 获取ListView对应的Adapter ListAdapter listAdapter = listView.g

android,解决ListView,GridView滑动冲突。

以gridView为例,如果gridView在里面,则重写GridView中的方法 /** * 重写该方法,达到使ListView适应ScrollView的效果 */protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.

android ListView中CheckBox错位的解决

貌似已经很晚了,但是还是想记下笔记,想让今天完满. 在ListView中加了checkBox,可是发现点击改变其选中状态的时候,发现其位置错乱.状态改变的并不是你选中的,百思不得其解.后面通过上网查资料,可是个说纷纭,但是我还是找到了解决办法. 在自定义的适配器中,对checkBox的设置如下: 记住两者的顺序,先对checkBox进行事件监听,再设置其状态.前提在布局中对checkBox的状态设为false. android ListView中CheckBox错位的解决,布布扣,bubuko.

重写ListView解决ListView内部ViewPaper滑动事件冲突问题

很简单 重写ListView 其他类似问题解决ScrollView嵌套ViewPager出现的滑动冲突问题 http://blog.csdn.net/zhangyiacm/article/details/37903071 package com.zy.myview; import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import androi

Scrollerview与listview或者gridview发生冲突

滑动冲突说实在的就是子view的滑动事件与父view的滑动事件的监听都在同时触发,而导致的activity的点击事件或者布局出问题 常见的就有Scrollerview与Scrollerview与listview或者gridview发生冲突,listview是RecycleView等等的代表.话说,其中listview和scrollerview冲突的时候发生的问题比较奇葩 其中,listview只能显示一条数据我就震惊了,多方查询后才发现是冲突问题.(还是那句作为初学者,积少成多,提高解决问题速度

Android中ListView与CheckBox结合----多选与记录

很多时候我们会用到ListView与CheckBox结合的东西,比如一个清单,可以用来多选,但是很多人似乎也在这个地方遇到很多问题,我刚开始学的时候也是遇到假选问题,当列表中数量多的之后,我勾选一个,滑动页面会发现条目也勾选上了, 这明显与我们的要求不符合,后来网上找了找资料,用HashMap来记录一个CheckBox的勾选记录就解决了 以下是实现的的一个小Demo 这是XML ListView 每个item文件清单 <?xml version="1.0" encoding=&q

解决 listview的item超过屏幕显示出现滚动的全选问题

1.listview的getcount与getchildcount,getcount>=getchildcount.getcount为所有的listdata的size值,getchildcount获得的是显示的值: 当itemsize<=显示屏的显示数量,getcount()=getchildcount(), 当itemsize >显示屏的显示数量,getcount> getchildcount; 2.问题原因: ListView+CheckBox数据超过一屏时数据乱序的原因主要是

Android基础入门教程——2.4.5 ListView之checkbox错位问题解决

Android基础入门教程--2.4.5 ListView之checkbox错位问题解决 标签(空格分隔): Android基础入门教程 本节引言: 作为ListView经典问题之一,如果你尝试过自定义ListView的item,在上面带有一个checkbox的话,那么 当你的item数超过了一页的话,就会出现这个问题,下面我们来分析下出现这种问题的原因,以及如何来 解决这个问题! 1.问题发生的原因: 这是网上找来的一幅关于ListView getView方法调用机制的一个图 上图中有一个Re