Welcome

首页 / 移动开发 / Android / 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mList = (ListView)findViewById(R.id.mList);//开始向presenter层请求数据new Presenter(this).load();}/*** presenter层将数据通过接口回调把数据传递给这个方法* 通过这个方法可以将数据项传递给适配器*/@Overridepublic 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() {@Overridepublic 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{/*** 实现数据的处理,方法中的参数是一个接口类型,所有传递过来的值都必须实现其定义的方法*/@Overridepublic 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();}@Overridepublic int getCount() {return data == null ? 0 : data.size();}@Overridepublic Object getItem(int i) {return data.get(i);}@Overridepublic long getItemId(int i) {return i;}@Overridepublic 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;}@Overridepublic 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时,下面的复用组件就不会想上面的运行结果一样被复用了,这样才是正常的选择了,想选择就选择,想取消就取消。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。