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列表数据需要加载的更 ...
随机推荐
- Springboot 整合 中国移动MAS HTTP1.0 实现短信发送服务(二)
原因:身份验证传入的参数包含中文企业名,因为本地编码格式是支持中文的:而客户的服务器中文却乱码,导致传给中国移动MAS服务器的是乱码的信息. 解决:非常简单,将中文信息转为UTF-8.例如(%E5%8 ...
- IntelliJ IDEA(Android Studio)设置代码的快捷编辑模板Live Templates
1.file---->setttings 2.editor--->live template 3.点击右侧的+ 4.设置模板 注意:Abbreviation为代码模板的缩写.
- LeetCode记录之13——Roman to Integer
能力有限,这道题采用的就是暴力方法,也只超过了39%的用户.需要注意的就是罗马数字如果IXC的后一位比前一位大的采取的是减的方式. Given a roman numeral, convert it ...
- 一款不错的Linux终端颜色设置
PS1="\[\e[37;40m\][\[\e[32;40m\]\u\[\e[37;40m\]@\h \[\e[36;40m\]\w\[\e[0m\]]\\$ " #步骤# vi ...
- 建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237
该逻辑对于删除第一个元素不适用. 这样的代码不优美 /** * Definition for singly-linked list. * struct ListNode { * int val; * ...
- c++ 编程调试秘笈
美.Vladimir Kushnir . O'REILLY. 人邮 .2013.1 c++大部分缺陷来源于c MyClass* object = new MyClass(); delete objec ...
- PIE SDK栅格数据的投影转换
1. 功能简介 为了适应不同数据显示分析的需要,数据的投影可以进行相应的转换,目前PIE SDK支持多种数据格式的投影转换,下面对栅格数据格式的投影转换功能进行介绍. 2. 功能实现说明 2.1. 实 ...
- mysql PXC集群方案总结
同时写集群内的所有机器 写性能依赖最慢的那个机器 读性能提高X倍
- 用 fmt格式化候时间
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <div ...
- python 爬虫系列01-连接mysql
爬虫学习中......................................... import pymysql conn = pymysql.connect(host=',database ...