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

Android自定义下拉刷新上拉加载

程序员文章站 2024-03-01 17:32:16
本文实例为大家分享了android自定义下拉刷新上拉加载的具体实现步骤,供大家参考,具体内容如下 实现的方式是swiperefreshlayout + recyclerv...

本文实例为大家分享了android自定义下拉刷新上拉加载的具体实现步骤,供大家参考,具体内容如下

实现的方式是swiperefreshlayout + recyclerview 的viewtype

首先看效果:

Android自定义下拉刷新上拉加载

总的思路:

Android自定义下拉刷新上拉加载

布局文件

<android.support.v4.widget.swiperefreshlayout
    android:layout_margintop="?attr/actionbarsize"
    android:id="@+id/one_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.recyclerview
      android:id="@+id/one_recyclerview"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      >

    </android.support.v7.widget.recyclerview>

  </android.support.v4.widget.swiperefreshlayout>

下拉刷新的实现思路

Android自定义下拉刷新上拉加载

用于测试的model

public class testmodel {
  private string mtitle;
  private string mdesc;
  private string mtime;

  public testmodel(string mtitle, string mdesc, string mtime) {
    this.mtitle = mtitle;
    this.mdesc = mdesc;
    this.mtime = mtime;
  }
  //...一堆getxxx ,setxxx方法
  //equals必写,添加数据时候用于判断
   @override
  public boolean equals(object o) {
    testmodel model = (testmodel) o;
    if (!mtitle.equals(model.getmtitle())) {
      return false;
    } else if (!mdesc.equals(model.getmdesc())) {
      return false;
    } else if (!mtime.equals(model.getmtitle())) {
      return false;
    }
    return true;
  }

模拟获取网络数据的代码

private class getdata {
    int size = 0 ;
    int max = 25; //数据的最大值

    public void setstart(int size) {
      this.size = size;
    }
    //根据size获取指定大小的list,最大不能超过max
    public list<testmodel> initdata(int size) {
      list<testmodel> mdatas = new arraylist<>();
      testmodel model = null;
      for (int i = start; i < ((size + start) > max ? max : (size + start)); i++) {
        model = new testmodel("title" + i, "desc" + i, "今天 11:30");
        mdatas.add(model);
      }
      start += size;
      return mdatas;

    }
  }

数据获取并通知初始化recyclerview

public void initdata() {
    if (getdata == null) {
      getdata = new getdata();
    }
    mlists = getdata.initdata(size); //获取默认显示的数量的item
    mhandler.sendemptymessage(refresh); //通知handler更新
  }

handler中用于处理第一次显示数据和以后刷新操作的代码

if (msg.what == refresh) {
if (madapter == null) {
madapter = new oneadapter(mcontext);
madapter.setmdatas(mlists);//设置数据
//...对适配器的设置,这里先省去,免得混淆
mrecyclerview.setlayoutmanager(new linearlayoutmanager(mcontext));
mrecyclerview.setadapter(madapter);
    } else {
     madapter.setmdatas(mlists);
     madapter.cleadncount();
     madapter.notifydatasetchanged();
   }
  initrefresh(); //判断refreshlayout是否在刷新,是的话取消刷新操作 .就不贴代码了显的乱糟糟

refreshlayout的刷新事件

mrefresh.setonrefreshlistener(new swiperefreshlayout.onrefreshlistener() {
   @override
   public void onrefresh() {
     new thread(mrunnable).start();//runnable调用了initdata()方法;
   }
   });

此时就可以对刷新操作做出响应了,与平时使用refreshlayout的操作一样

上拉刷新的实现思路(主要在适配器中,activity中只需要一个当需要加载更多的时候更新数据源就行)

Android自定义下拉刷新上拉加载

普通内容的布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.cardview xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_margin="5dp"
  android:orientation="vertical"
  tools:context=".mainactivity">

  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <imageview
      android:scaletype="centerinside"
      android:id="@+id/item_head"
      android:layout_width="70dp"
      android:layout_height="70dp"
      android:layout_gravity="center"
      android:layout_margin="5dp"
      android:src="@mipmap/ic_launcher" />

    <linearlayout
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:layout_marginleft="5dp"
      android:layout_weight="1"
      android:orientation="vertical">

      <textview
        android:id="@+id/item_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:text="title"
        android:textsize="20sp" />

      <textview
        android:id="@+id/item_desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:text="desc"
        android:textsize="16sp" />

      <textview
        android:id="@+id/item_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|right"
        android:layout_marginright="14dp"
        android:layout_weight="1"
        android:gravity="center_vertical|right"
        android:text="time"
        android:textsize="20sp" />
    </linearlayout>

  </linearlayout>

</android.support.v7.widget.cardview>

加载更多的内容布局(默认显示progressbar,没有更多的图标隐藏)

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="40dp"
  android:orientation="horizontal">

  <imageview
    android:id="@+id/load_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical|right"
    android:layout_weight="1"
    android:scaletype="centerinside"
    android:src="@mipmap/ic_launcher"
    android:visibility="gone" />

  <progressbar
    android:id="@+id/load_progress"
    style="@style/widget.appcompat.progressbar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical|right"
    android:layout_weight="1" />

  <textview
    android:id="@+id/load_tv"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:gravity="center_vertical|left"
    android:text="正在加载更多...."
    android:textcolor="@color/colorblank"
    android:textsize="20sp" />

</linearlayout>

itemcount(因为我们要在最后显示信息,所以item的总数应该是加1,但是也是分情况的:

@override
  public int getitemcount() {
    if (mdatas.size() > minshowload) { //当前item能将屏幕显示满

      return mdatas.size() + 1; //则默认显示加载或者没有更多
    }
    return mdatas.size(); //如果不能显示满,则不显示加载和没有更多
  }

getviewtype(根据不同的位置显示不同的type)

@override
  public int getitemviewtype(int position) {
    if (position == mdatas.size()) {
      return viewtype_load; //最后一个显示加载信息
    }
    return viewtype_content;//否则显示正常布局
  }

正常内容的viewholder

//内容布局
  private class contentviewholder extends recyclerview.viewholder {
    private textview mtitle;
    private textview mdesc;
    private textview mtime;
    private imageview mhead;
    private view itemview;

    public contentviewholder(view itemview) {
      super(itemview);
      this.itemview = itemview;
      mtitle = (textview) itemview.findviewbyid(r.id.item_title);
      mdesc = (textview) itemview.findviewbyid(r.id.item_desc);
      mtime = (textview) itemview.findviewbyid(r.id.item_time);
      mhead = (imageview) itemview.findviewbyid(r.id.item_head);
    }
  }

加载信息的viewholder

//加载更多的布局  (用于显示正在加载和没有更多
  private class loadmoreviewholder extends recyclerview.viewholder {
    private imageview mimage;
    private progressbar mprogress;
    private textview mmsg;

    public loadmoreviewholder(view itemview) {
      super(itemview);
      mimage = (imageview) itemview.findviewbyid(r.id.load_image);
      mprogress = (progressbar) itemview.findviewbyid(r.id.load_progress);
      mmsg = (textview) itemview.findviewbyid(r.id.load_tv);
    }
  }

oncreateviewholder中初始化不同的viewholder

  @override
  public recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) {
    view itemview = null;
    switch (viewtype) {
      case 1:
        itemview = layoutinflater.from(mcontext).inflate(r.layout.load_layout, parent, false);
        return new loadmoreviewholder(itemview);
      case 2:
        itemview = layoutinflater.from(mcontext).inflate(r.layout.item_test, parent, false);
        return new contentviewholder(itemview);
    }
    return null;
  }

定义一个回调,用于当显示加载的时候通知activity更新数据

public interface onloadmorelistener {
    void loadmore();
  }
  //全局变量
private onloadmorelistener onloadmorelistener;

onbindviewholder(对不同的情况进行数据显示)

@override
  public void onbindviewholder(recyclerview.viewholder holder, int position) {
    if (holder instanceof contentviewholder) {
      testmodel model = mdatas.get(position);
      ((contentviewholder) holder).mtitle.settext(model.getmtitle());
      ((contentviewholder) holder).mdesc.settext(model.getmdesc());
      ((contentviewholder) holder).mtime.settext(model.getmtime());
    } else if (holder instanceof loadmoreviewholder) {
      if (mdatas.size() < itemscount) { //没有更多
        ((loadmoreviewholder) holder).mmsg.settext("没有更多了~~~");
        ((loadmoreviewholder) holder).mprogress.setvisibility(view.gone);
        ((loadmoreviewholder) holder).mimage.setvisibility(view.visible);
      } else {
        onloadmorelistener.loadmore();
        ((loadmoreviewholder) holder).mmsg.settext("正在加载更多....");
        ((loadmoreviewholder) holder).mprogress.setvisibility(view.visible);
        ((loadmoreviewholder) holder).mimage.setvisibility(view.gone);
      }
    }
  }

加载更多的回调在activity中的使用

madapter.setonloadmorelistener(new oneadapter.onloadmorelistener() {
    @override
    public void loadmore() {
   //增加数据到数据源中
   //调用adapter的adddata方法
   //更新适配器显示
  }
}

至此下拉刷新上拉加载就完成了,demo地址:swipetorefreshtest

以上就是android自定义下拉刷新上拉加载的全部内容,希望能给大家一个参考,也希望大家多多支持。