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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决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;
    }
}

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

                                                                                                                   




以上是关于如何解决ListView与CheckBox的冲突问题的主要内容,如果未能解决你的问题,请参考以下文章

完美解决ListView和CheckBox焦点冲突及复用时CheckBox错位等一系列问题

Android学习笔记之ListView与Item的焦点冲突处理

Android学习笔记之ListView与Item的焦点冲突处理

关于ListView中item与子控件抢夺焦点的解决方法

ListView之checkbox错位问题解决

如何获取listview里选中的checkbox