RecycleView + SwipeRefreshLayout 实现下拉刷新和底部自动加载
前段时间项目里面使用了RecycleView 但是里面的刷新和加载都是框架里面封装好的,直接使用
这几天比较闲就自己来实现以下.
因为SwipeRefreshLayout是一个下拉刷新控件所有直接和RecycleView结合使用就行了
布局文件
<?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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="tianliang.com.mvpdemo.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/SwipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
主代码
在里面使用了 butterknife 关联控件
public class MainActivity extends AppCompatActivity { @Nullable
@BindView(R.id.RecyclerView)
RecyclerView mRecyclerView;
@Nullable
@BindView(R.id.SwipeRefreshLayout)
SwipeRefreshLayout mSwipeRefreshLayout; private LinearLayoutManager mLayoutManager;
private List<String> data; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
} private void initData() {
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//初始化数据
data = new ArrayList<>();
for (int i = 1; i < 30; i++) {
data.add("数据+" + i);
}
RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(data);//设置adpater
mRecyclerView.setAdapter(mAdapter);
//SwipeRefreshLayout监听
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override
public void onRefresh() {//模仿加载网络数据
new Handler().postDelayed(new Runnable() { @Override
public void run() {//每次刷新一条数据
data.add(0, "刷新出来的数据");
mRecyclerView.getAdapter().notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
}, 2000);
}
});
mRecyclerView.setOnScrollListener(new OnRcvScrollListener(){//使用自定义的RecycleView的底部监听
@Override
public void onBottom() {//接口回调
new Handler().postDelayed(new Runnable() {//模仿网络请求
@Override
public void run() {
if (data.size() <= 50) {
for (int i = 1; i < 5; i++) {
data.add("加载更多+" + i);
}
}
mRecyclerView.getAdapter().notifyDataSetChanged();//刷新adapter
}
}, 2000);
}
}
);
}
}
RecycleView的底部监听
使用的是 http://www.cnblogs.com/tianzhijiexian/p/4397552.html 写好的工具类
public abstract class OnRcvScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener { private String TAG = getClass().getSimpleName(); public static enum LAYOUT_MANAGER_TYPE {
LINEAR,
GRID,
STAGGERED_GRID
} /**
* layoutManager的类型(枚举)
*/
protected LAYOUT_MANAGER_TYPE layoutManagerType; /**
* 最后一个的位置
*/
private int[] lastPositions; /**
* 最后一个可见的item的位置
*/
private int lastVisibleItemPosition;
/* *//**
* 是否正在加载
*//*
private boolean isLoadingMore = false;*/ /**
* 当前滑动的状态
*/
private int currentScrollState = 0; @Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy); RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
// int lastVisibleItemPosition = -1;
if (layoutManagerType == null) {
if (layoutManager instanceof LinearLayoutManager) {
layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR;
} else if (layoutManager instanceof GridLayoutManager) {
layoutManagerType = LAYOUT_MANAGER_TYPE.GRID;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID;
} else {
throw new RuntimeException(
"Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");
}
} switch (layoutManagerType) {
case LINEAR:
lastVisibleItemPosition = ((LinearLayoutManager) layoutManager)
.findLastVisibleItemPosition();
break;
case GRID:
lastVisibleItemPosition = ((GridLayoutManager) layoutManager)
.findLastVisibleItemPosition();
break;
case STAGGERED_GRID:
StaggeredGridLayoutManager staggeredGridLayoutManager
= (StaggeredGridLayoutManager) layoutManager;
if (lastPositions == null) {
lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];
}
staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
lastVisibleItemPosition = findMax(lastPositions);
break;
} } @Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
currentScrollState = newState;
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE &&
(lastVisibleItemPosition) >= totalItemCount - 1)) {
onBottom();
}
} @Override
public abstract void onBottom() ; private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value > max) {
max = value;
}
}
return max;
}
}
回调接口
public interface OnBottomListener {
void onBottom();
}
apdater
根据条目是否是最后一条来显示对应的hoder
public class RecyclerViewAdapter extends RecyclerView.Adapter {
private final List<String> mData;
private int TYPE_FOOTER = 1;//加载更多
private int TYPE_NORMAL = 0;//itme public RecyclerViewAdapter(List<String> data) {
mData = data;
} @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER) {//加载更多
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapet, parent, false);
footerHodler footer = new footerHodler(view,mData);
return footer;
}
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itmeadapet, parent, false);
itmeHoder hoder = new itmeHoder(view, mData.get(viewType));
return hoder;
} @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position) == TYPE_NORMAL && holder instanceof itmeHoder) {
((itmeHoder) holder).setData(mData.get(position));
}else if (getItemViewType(position) == TYPE_FOOTER && holder instanceof footerHodler){
((footerHodler)holder).setData();
}
} @Override
public int getItemCount() {
return mData.size() + 1;
} @Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
return TYPE_FOOTER;//最后一条数据
}
return TYPE_NORMAL;
}
}
ok,大体就是这样了
RecycleView + SwipeRefreshLayout 实现下拉刷新和底部自动加载的更多相关文章
- Android如何定制一个下拉刷新,上滑加载更多的容器
前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...
- 一个简单的适用于Vue的下拉刷新,触底加载组件
一个简单的适用于Vue的上拉刷新,触底加载组件,没有发布npm需要时直接粘贴定制修改即可 <template> <div class="list-warp-template ...
- RecyclerViewLoadMoreDemo【封装上拉加载功能的RecyclerView,搭配SwipeRefreshLayout实现下拉刷新】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 封装含有上拉加载功能的RecyclerView,然后搭配SwipeRefreshLayout实现下拉刷新.上拉加载功能. 在项目中将 ...
- Android 编程下如何调整 SwipeRefreshLayout 的下拉刷新距离
SwipeRefreshLayout 的下拉刷新距离比较短,并且也没有提供设置下拉距离的 API,但是看 SwipeRefreshLayout 的源码,会发现有一个内部变量 mDistanceToTr ...
- 利用Swiperefreshlayout实现下拉刷新功能的技术探讨
在常见的APP中通常有着下拉页面从而达到刷新页面的功能,这种看似简单的功能有着花样繁多的实现方式.而利用Swiperefreshlayout实现下拉刷新功能则是其中比较简明扼要的一种. 一般来说,在竖 ...
- Android之下拉刷新,上啦加载的实现(一)
转载地址http://blog.csdn.net/leehong2005/article/details/12567757#t5 前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但 ...
- android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
android ListView的上部下拉刷新下部点击加载更多具体实现及拓展 ListView下拉刷新,上拉自动加载更多 下拉刷新以及加载更多
- 当滚动条滚动到页面底部自动加载增加内容的js代码
这篇文章主要介绍了如何使用javscript实现滚动条滚动到页面底部自动加载增加页面内容,需要的朋友可以参考下..1,注册页面滚动事件,window.onscroll = function(){ }; ...
- UWP-ListView到底部自动加载更多数据
原文:UWP-ListView到底部自动加载更多数据 ListView绑定的数据当需要“更多”时自动加载 ListView划到底部后,绑定的ObservableCollection列表数据需要加载的更 ...
随机推荐
- 解决CentOS查询不到ip
问题:登陆操作系统,输入ip addr 也可以输入ifconfig查看ip,发现ens33目录中没有inet属性 解答:查看ens33的网卡配置: vi /etc/sysconfig/network- ...
- 20165224 陆艺杰 Exp3 免杀原理与实践
杀软是如何检测出恶意代码的? 识别代码特征码 监测像后门的行为 (2)免杀是做什么? 让后面程序不被安全软件发现 (3)免杀的基本方法有哪些? 多方式编码 半手工shellcode编程 完全自己写没有 ...
- CF1012B Chemical table(构造)
[Luogu-CF1012B] 还有重题 P5089[eJOI2018]元素周期表 题解原话 : 可以发现这个过程是不改变二分图中的连通分量的个数的 答案就是 连通分量数-1 证明 : 设一行或一列为 ...
- UVA - 10589 构造最优化函数 DP好题
题意:给定一个图,节点可以放灯,要求用最少的灯覆盖所有的边(每盏灯能覆盖该节点邻接的边),满足条件的同时求该前提下尽量多的被两盏灯照亮的边数 条件二转化为求尽量少的被一盏灯照亮的边数,两个条件都是求m ...
- Dear friends:
To realize the value of ONE YEAR想知道一整年的价值ask the student who has failed a class就去问被当过的学生To realize ...
- 1093 字符串A+B (20 分)
给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集.要求先输出 A,再输出 B,但重复的字符必须被剔除. 输入格式: 输入在两行中分别给出 A 和 B,均为长度不超过 106 ...
- 【网络】EIGRP负载均衡、手工汇总、泄露明细、安全认证
基于6.6.6.6/24访问13.1.1.1/24进行负载均衡实例图 一.等价负载均衡 等价负载均衡前,R5路由器背后的6.6.6.6/24访问R1的13.1.1.1/24, 从15.1.1.0/24 ...
- PIE SDK算法的异步调用
1.算法功能简介 异步方法一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作.异步方法通常会在另外一个线程中,“真实”地执行着.整个过程,不会阻碍调用者的工作. PIE SDK支持算法功能的执 ...
- 用Verilog语言设计一个3-8译码器
case语句 if_case语句 源码下载 Github >>
- oracle 集群RAC搭建--环境准备
一,环境介绍 目前我本身环境已经有DG,正在尝试重做搭建.如需完成请移步往期文章--搭建DG