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列表数据需要加载的更 ...
随机推荐
- Dubbo基础配置
服务启动检查配置 默认check=true dubbo:reference check=“false” 关闭某个服务的启动时检查:(没有提供者时报错) dubbo:consumer check=“ ...
- R语言结果输出方法
输出函数:cat,sink,writeLines,write.table 根据输出的方向分为输出到屏幕和输出到文件. 1.cat函数即能输出到屏幕,也能输出到文件. 使用方式:cat(... , fi ...
- LeetCode268.缺失数字
268.缺失数字 描述 给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数. 示例 示例 1: 输入: [3,0,1] 输出: 2 示例 ...
- 洛谷 P2495 [SDOI2011]消耗战(虚树,dp)
题面 洛谷 题解 虚树+dp 关于虚树 了解一下 具体实现 inline void insert(int x) { if (top == 1) {s[++top] = x; return ;} int ...
- HDU - 1525 博弈 暴力分析
先来看看比较显然的几个局面 (a,0) 先手必败 (a,a) 先手必胜 (a,ak) 先手必胜 (a,ak+r),k>1 先手必胜,因为先手有主动权把(a,r)让给后手或留给自己 对于开局(a, ...
- Hadoop基础入门
一.hadoop是什么? (1)Hadoop是一个开源的框架,可编写和运行分布式应用处理大规模数据,是专为离线和大规模数据分析而设计的,并不适合那种对几个记录随机读写的在线事务处理模式.Hadoop= ...
- 1093 字符串A+B (20 分)
给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集.要求先输出 A,再输出 B,但重复的字符必须被剔除. 输入格式: 输入在两行中分别给出 A 和 B,均为长度不超过 106 ...
- Python学习 day06
一.== 和 is == 比较的是值 is 比较的是地址 id() -- 返回对象的内存地址 例: 赋值操作是将地址赋给变量 Python 中会实现创建一个小型的整形池,范围为 [-5,25 ...
- Nginx设置日志分割方法
目标:nginx cronolog日志分割配置文档,每分钟分割一次NGINX访问日志. 大体步骤如下: 1.nginx日志配置 access_log /var/log/nginx/access.log ...
- 东拼西凑 vim配置-更新
"============================================================= "========================== ...