SwipeRefreshLayout 是谷歌公司推出的用于下拉刷新的控件,在Version 19.1之后SwipeRefreshLayout 被放到support v4中。我们在前面也已经说过一个SwipeRefreshLayout和ListView实现上拉加载、下拉刷新的例子。而现在RecyclerView也已作为实现列表功能的首选组件,而它本身并没有实现上拉加载、下拉刷新的功能,本节我们就来利用SwipeRefreshLayout 和RecyclerView来实现上拉加载、下拉刷新的功能。
SwipeRefreshLayout 常用的方法如下:
setOnRefreshListener(OnRefreshListener):下拉刷新监听器,当用户下拉的时候会触发 setRefreshing(boolean):设置SwipeRefreshLayout当前是否处于刷新状态,一般是在请求数据的时候设置为true,在数据被加载到View中后,设置为false。 isRefreshing():检查是否处于刷新状态 setColorSchemeResources():设置进度条的颜色主题,最多设置四种,以前的setColorScheme()方法已经弃用了。 setProgressViewOffset(boolean scale, int start, int end) 调整进度条距离屏幕顶部的距离
布局文件很简单
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.xmr.recycleandswiperefresh.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/srl_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/ryv_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
接着在Activity中获取SwipeRefreshLayout控件并且设置OnRefreshListener监听器,同时实现里边的onRefresh()方法,在该方法中进行网络请求最新数据,然后刷新RecyclerView列表同时设置SwipeRefreshLayout的显示效果。具体代码如下:
mSwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//实际项目中这里一般是用网络请求获取数据
mList.add(
"下拉刷新")
;
mAdapter.notifyDataSetChanged()
;
mSwipeRefreshLayout.setRefreshing(
false)
;
}
})
;
RecyclerView的实现: 第一种,下拉刷新和上拉刷新都用SwipeRefreshLayout 自带的效果
mRecyclerView.setOnScrollListener(
new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView
,
int newState) {
super.onScrollStateChanged(recyclerView
, newState)
;
if (newState == RecyclerView.
SCROLL_STATE_IDLE
&&
lastVisibleItem +
1 ==
mAdapter.getItemCount()) {
mSwipeRefreshLayout.setRefreshing(
true)
;
//实际项目中这里一般是用网络请求获取数据
mList.add(
"上拉加载")
;
//为了有刷新的效果,延迟关闭刷新效果
mSwipeRefreshLayout.postDelayed(
new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(
false)
;
mAdapter.notifyDataSetChanged()
;
}
}
, 2000)
;
}
}
@Override
public void onScrolled(RecyclerView recyclerView
, int dx
, int dy) {
super.onScrolled(recyclerView
, dx
, dy)
;
//判断是当前layoutManager是否为LinearLayoutManager
// 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
if (
linearLayoutManager instanceof LinearLayoutManager) {
//获取最后一个可见view的位置
lastVisibleItem =
linearLayoutManager.findLastVisibleItemPosition()
;
//获取第一个可见view的位置
// int firstItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
}
}
})
;
效果如下:
第二种实现下拉刷新用SwipeRefreshLayout 自带的效果, 上拉加载我们可以给RecyclerView 添加一个类似FooterView的item。 我们在Adapter中实现:
package com.xmr.recycleandswiperefresh
;
import android.content.Context
;
import android.support.v7.widget.RecyclerView
;
import android.view.LayoutInflater
;
import android.view.View
;
import android.view.ViewGroup
;
import android.widget.LinearLayout
;
import android.widget.TextView
;
import java.util.List
;
/**
* Created by Administrator on 2016/9/13.
*/
public class RefreshAdapter1
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context
mContext;
private List<String>
mDatas;
private static final int TYPE_ITEM =
0; //普通Item View
private static final int TYPE_FOOTER =
1; //底部FootView
//已经到底了
public static final int PULLUP_LOAD_MORE =
0;
//正在加载中
public static final int LOADING_MORE =
1;
//上拉加载状态-默认为0
private int load_more_status =
0;
public RefreshAdapter1(Context mContext
, List<String> mDatas) {
this.
mContext = mContext
;
this.
mDatas = mDatas
;
}
@Override
public RecyclerView.ViewHolder
onCreateViewHolder(ViewGroup parent
, int viewType) {
//进行判断显示类型,来创建返回不同的View
if (viewType ==
TYPE_ITEM) {
View view = LayoutInflater.
from(parent.getContext()).inflate(
R.layout.
item_recycler_refresh, null)
;
// view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
// LayoutParams.WRAP_CONTENT));
return new ItemHolder(view)
;
}
// type == TYPE_FOOTER 返回footerView
else if (viewType ==
TYPE_FOOTER) {
View view = LayoutInflater.
from(parent.getContext()).inflate(
R.layout.
item_recycler_footer, null)
;
// view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
// LayoutParams.WRAP_CONTENT));
return new FooterHolder(view)
;
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder
, int position) {
if (holder
instanceof ItemHolder) {
ItemHolder itemHolder = (ItemHolder) holder
;
itemHolder.
textView.setText(
mDatas.get(position))
;
}
else if (holder
instanceof FooterHolder) {
FooterHolder footHolder = (FooterHolder) holder
;
//这句如果不注释,那么底部就会有添加的一个item
footHolder.
linearLayout.setVisibility(View.
GONE)
;
switch (
load_more_status) {
case PULLUP_LOAD_MORE:
footHolder.
linearLayout.setVisibility(View.
GONE)
;
// footHolder.textView.setText("已经到底了");
break;
case LOADING_MORE:
footHolder.
linearLayout.setVisibility(View.
VISIBLE)
;
footHolder.
textView.setText(
"正在加载更多数据...")
;
break;
}
}
}
@Override
public int getItemCount() {
return mDatas ==
null ?
0 :
mDatas.size() +
1;
}
@Override
public int getItemViewType(
int position) {
// 最后一个item设置为footerView
if (position +
1 == getItemCount()) {
return TYPE_FOOTER;
}
else {
return TYPE_ITEM;
}
}
class ItemHolder
extends RecyclerView.ViewHolder {
public TextView
textView;
public ItemHolder(View itemView) {
super(itemView)
;
textView = (TextView) itemView.findViewById(R.id.
tv_item_recycler_refresh)
;
}
}
class FooterHolder
extends RecyclerView.ViewHolder {
public TextView
textView;
public LinearLayout
linearLayout;
public FooterHolder(View itemView) {
super(itemView)
;
textView = (TextView) itemView.findViewById(R.id.
tv_item_recycler_footer)
;
linearLayout = (LinearLayout) itemView.findViewById(R.id.
ll_item_recycler_footer)
;
}
}
/**
* //上拉加载更多
* PULLUP_LOAD_MORE=0;
* //正在加载中
* LOADING_MORE=1;
* //加载完成已经没有更多数据了
* NO_MORE_DATA=2;
*
* @param status
*/
public void changeMoreStatus(
int status) {
load_more_status = status
;
notifyDataSetChanged()
;
}
}
而对RecyclerView的上拉加载,我们这样实现:
mRecyclerView.setOnScrollListener(
new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView
,
int newState) {
super.onScrollStateChanged(recyclerView
, newState)
;
if (newState == RecyclerView.
SCROLL_STATE_IDLE
&&
lastVisibleItem +
1 ==
mAdapter.getItemCount()) {
Log.
i(
">>>>>", ">>>>" +
lastVisibleItem +
">>>" +
mAdapter.getItemCount())
;
mAdapter.changeMoreStatus(
mAdapter.
LOADING_MORE)
;
//为了有刷新的效果,延迟2s修改状态
new Handler().postDelayed(
new Runnable() {
@Override
public void run() {
mAdapter.changeMoreStatus(RefreshAdapter1.
PULLUP_LOAD_MORE)
;
//实际项目中这里一般是用网络请求获取数据
mList.add(
"上拉加载")
;
}
}
, 2000)
;
}
}
@Override
public void onScrolled(RecyclerView recyclerView
, int dx
, int dy) {
super.onScrolled(recyclerView
, dx
, dy)
;
//判断是当前layoutManager是否为LinearLayoutManager
// 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
if (
linearLayoutManager instanceof LinearLayoutManager) {
//获取最后一个可见view的位置
lastVisibleItem =
linearLayoutManager.findLastVisibleItemPosition()
;
//获取第一个可见view的位置
// int firstItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
}
}
})
;
}
最终效果如下:
不过,现在也有点bug,如果列表没有占满屏幕的话,下拉刷新的时候也会同时触发上拉加载的效果,大家如果有好的解决方案的话可以给我说下,先谢谢了
参考:
http://blog.csdn.net/dalancon/article/details/46125667
http://www.cnblogs.com/xiaoyaoxia/p/4977125.html
http://blog.csdn.net/developer_jiangqq/article/details/49992269
http://blog.csdn.net/salute_li/article/details/52118504
http://www.cnblogs.com/csonezp/p/5050324.html
转载请注明原文地址: https://ju.6miu.com/read-1124822.html