欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-03-06 17:52:50
mvp模式 listview中嵌入checkbox的使用 本文写的是一个小demo,如何在listview中嵌入checkbox配合使用,本篇文章与前面的嵌入button...

mvp模式 listview中嵌入checkbox的使用

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

程序基本框架如下:

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

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方法中的注释的代码所产生的运行效果图:

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

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

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

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

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

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