Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義下拉刷新上拉加載

Android自定義下拉刷新上拉加載

編輯:關於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"
    
    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自定義下拉刷新上拉加載的全部內容,希望能給大家一個參考,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved