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

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

实现的方式是SwipeRefreshLayout + RecyclerView 的VIewType

首先看效果:

总的思路:

布局文件

<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>

下拉刷新的实现思路

用于测试的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中只需要一个当需要加载更多的时候更新数据源就行)

普通内容的布局

<?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自定义下拉刷新上拉加载的全部内容,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Android中替换WebView加载网页失败时的页面

    我们用webView去请求一个网页链接的时候,如果请求网页失败或无网络的情况下,它会返回给我们这样一个页面,如下图所示: 上面这个页面就是系统自带的页面,你觉得是不是很丑?反正小编本人觉得非常丑,很难看,于是乎小编就在想能不能自定义一个页面,当数据请求失败时让系统来加载我们自定义好的页面?上网查了很多资料,都没有关于这个问题的解决方法(反正我是没有找到),经过小编的不断琢磨,今天终于实现了这个功能.以下就是本人自定义实现的数据加载失败时的页面: 这样看起来是不是觉得很高大尚.这和我们真正拿到数据

  • Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

  • Android开发实现自定义新闻加载页面功能实例

    本文实例讲述了Android开发实现自定义新闻加载页面功能.分享给大家供大家参考,具体如下: 一.概述: 1.效果演示: 2.说明:在新闻页面刚加载的时候,一般会出现五种状态 未知状态(STATE_UNKNOW).空状态(STATE_EMPTY).加载中(STATE_LOADING).错误(STATE_ERROT).成功(STATE_SUCCESS) 因为每个Detail页面都会出现,所以我们可以把他们封装成一个LoadPage的自定义view,可以复用 二.实现: 1.首先的定义三个布局,为什

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android自定义Dialog实现文字动态加载效果

    之前在技术问答上面看到一个提问 "加载中-" 后面三个点是动态的,这么一个效果实现.想来想去,好像没想到好的处理方式. 尝试了一下,以一个最笨的方式实现了.先来看一下效果 : 我是通过自定义一个Dialog,加载中的效果,是在Dialog内部实现的,进度还是从Activity里面控制的. 下面是Dialog实现类: public class CustomDialog extends AlertDialog { public CustomDialog(Context context) {

  • Android自定义加载控件实现数据加载动画

    本文实例为大家分享了Android自定义加载控件,第一次小人跑动的加载效果眼前一亮,相比传统的PrograssBar高大上不止一点,于是走起,自定义了控件LoadingView去实现动态效果,可直接在xml中使用,具体实现如下 package com.*****.*****.widget; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.util.

  • Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { switch(position){ case 0: fragments=new Fragmnet01(); break; case

  • 加载页面遮挡耗时操作任务页面--第三方开源之AndroidProgressLayout

    AndroidProgressLayout实现为界面添加圆形进度条.调用setprogress()方法显示和隐藏进度条 在Android的开发中,往往有这种需求,比如一个耗时的操作,联网获取网络图片.内容,数据库耗时读写等等,在此耗时操作过程中,开发者也许不希望用户再进行其他操作(其他操作可能会引起逻辑混乱),而此时需要给用户一个额外的加载页面遮挡住主逻辑代码的运行,待主页面的耗时操作完成后,自动消失这样加载过度页面,恢复出正常应该显示的页面. 举个实际的例子,如代码使用Android WebV

  • Android自定义加载loading view动画组件

    在github上找的一个有点酷炫的loading动画https://github.com/Fichardu/CircleProgress 我写写使用步骤 自定义view(CircleProgress )的代码 package com.hysmarthotel.view; import com.hysmarthotel.roomcontrol.R; import com.hysmarthotel.util.EaseInOutCubicInterpolator; import android.ani

  • Android中自定义加载样式图片的具体实现

    先让大家看看效果图吧,相信很多Android初学者都想知道这中效果是怎么实现的,来上图: 想实现上面这张图中的自定义加载样式,其实很简单,首先我们需要的布局组件有ProcessBar和TextView,下面是布局文件的代码(只是加载的页面的布局): 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.an

  • Android实现自定义加载框的代码示例

    App在与服务器进行网络交互的时候,需要有一个提示的加载框,如图: 此时我们可以自定义一个加载中的对话框,代码如下: public class LoadingDialog extends Dialog { private static final int CHANGE_TITLE_WHAT = 1; private static final int CHNAGE_TITLE_DELAYMILLIS = 300; private static final int MAX_SUFFIX_NUMBER

随机推荐