Android MVP模式 ListView中嵌入checkBox的使用

MVP模式 ListView中嵌入checkBox的使用

本文写的是一个小demo,如何在ListView中嵌入checkBox配合使用,本篇文章与前面的嵌入Button类似,同样的采用MVP模式的写代码,本次案例中会有几个小细节,我将会在案例中介绍。

程序基本框架如下:
这里写图片描述

View层:

MainActivity.java

public class MainActivity extends AppCompatActivity implements ViewInter<MyBean>{
    //ListView的控件名
    private ListView mList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mList = (ListView)findViewById(R.id.mList);
        //开始向presenter层请求数据
        new Presenter(this).load();
    }
    /**
    * presenter层将数据通过接口回调把数据传递给这个方法
    * 通过这个方法可以将数据项传递给适配器
    */
    @Override
    public void showData(List<MyBean> myBeen) {
        MyAdapter adapter = new MyAdapter(myBeen);
        mList.setAdapter(adapter);
    }
}

ViewInter.java

/**
*   view层所有的界面更新,请求数据等功能都写在此接口,方便扩展
*/
public interface ViewInter<T> {
    void showData(List<T> t);
}
Presenter层:

Presenter.java

public class Presenter {
    //view层的对象,主要调用其子类自身的方法,然后回传数据
    ViewInter<MyBean> vi;
    //model层的对象,主要调用其子类功能,实现数据获取
    ModelInter mi;
    /**
    * 只需要传递view层的引用即可,model层的数据其由自身去处理
    */
    public Presenter(ViewInter<MyBean> vi){
        this.vi = vi;
        mi = new ModelImp();
    }
    /**
    * 该方法的主要功能就是负责数据的传递和通知处理数据
    */
    public void load(){
        //调用mi.getData方法,可以获取需要的数据,然后回调给view层
       mi.getData(new ModelInter.DealData() {
           @Override
           public void setData() {
               List<MyBean> data = new ArrayList<>();
               for(int i = 0; i < 10; i++){
                   MyBean bean = new MyBean();
                   //这里是随机生成实体类中的数据,也就是设置复选框是否默认为选上状态
                   bean.setChecked(Math.random() > 0.5 ? true : false);
                   data.add(bean);
               }
               //回调传递数据
               vi.showData(data);
           }
       });
    }
}
Model层:

ModelInter.java

/**
* 所有模型层的功能都可以写在此接口中,此接口方便扩展新功能
*/
public interface ModelInter {
    void getData(DealData dealData);
    public interface DealData{
        void setData();
    }
}

ModelImp.java

public class ModelImp implements ModelInter{
    /**
    * 实现数据的处理,方法中的参数是一个接口类型,所有传递过来的值都必须实现其定义的方法
    */
    @Override
    public void getData(DealData dealData) {
        dealData.setData();
    }
}

Adapter.java

public class MyAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {
    //定义一个类似于map集合的对象,其效率会比map更高,用来保存复选框当前被用户点击后的状态
    private SparseArray<Boolean> array;
    private Context context;
    private List<MyBean> data;

    public MyAdapter(List<MyBean> data) {
        this.data = data;
        array = new SparseArray();
    }

    @Override
    public int getCount() {
        return data == null ? 0 : data.size();
    }

    @Override
    public Object getItem(int i) {
        return data.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MyBean bean = data.get(position);
        if (context == null)
            context = parent.getContext();
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
            holder = new ViewHolder();
            holder.mTv = (TextView) convertView.findViewById(R.id.mTv);
            holder.mCheck = (CheckBox) convertView.findViewById(R.id.mCheck);
            convertView.setTag(holder);
        }
        holder = (ViewHolder) convertView.getTag();
        holder.mTv.setText("复选框" + position);
        //设置复选框的监听事件
        holder.mCheck.setOnCheckedChangeListener(this);
        holder.mCheck.setText("编程" + position);
        //将对应位置设置到tag中
        holder.mCheck.setTag(R.id.check, position);
        //首先判断数据项中的数据是否为true,如果为true则设置其默认值
       // if(data.get(position).isChecked())  //已注释
       //    holder.mCheck.setChecked(data.get(position).isChecked());//已注释
        //将用户选择的状态保存到对应的item复选框上  
       // holder.mCheck.setChecked(array.get(position, false));//已注释
        return convertView;
    }


    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        //每次触发事件的时候,都拿到对应item位置的值
       // int i = (int) compoundButton.getTag(R.id.check);//已注释
        //然后将状态保存到集合中
       // array.put(i, b);//已注释
        //并且修改数据项的值。
       // data.get(i).setChecked(b);//已注释
    }

    static class ViewHolder {
        TextView mTv;
        CheckBox mCheck;
    }
}

MyBean.java

//数据项对象
public class MyBean {
    boolean isChecked;

    public boolean isChecked() {
        return isChecked;
    }

    public void setChecked(boolean checked) {
        isChecked = checked;
    }
}

基本的代码都已经实现,我们来看看如果缺少MyAdapter.java中的getView方法中的注释的代码所产生的运行效果图:
这里写图片描述

从这个运行效果来看,我们明显可以看出一下小BUG,一开始的时候复选框都是没有选中,当我们自己选中第一个复选框的时候,我们往下拖动的时候,你会看到,复选框7明显也跟着被选上了,当我们在此选中复选框2的时候,复选框8也随之选中了,那么这是什么原因呢,这是因为在ListView的一个复用控件机制导致的,关于此问题,本博客中前面的基础已经讲解原理,本案例中就不做详细讲解。

最后我们看下取消那些注释的代码后的运行结果图:

这里写图片描述

从这个运行结果可以看到,由于默认数据选择的是1 、 2 、5 当我们取消1、2选择0时,下面的复用组件就不会想上面的运行结果一样被复用了,这样才是正常的选择了,想选择就选择,想取消就取消。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值