package com.gan.myrecycleview;

import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import com.gan.myrecycleview.wrapper.LoadMoreWrapper; import java.util.List; /**
* 用途: 自定义recycleview实现下拉刷新和自动加载
* 创建者:ganyufei
* 时间: 2017/2/8
*/ public class MyRecycleView<T> extends LinearLayout { private RecyclerView recyclerView;
private SwipeRefreshLayout swipeRfl;
// private LinearLayoutManager layoutManager;
private SwipeRefreshLayout.OnRefreshListener mRefreshListener;
private CommonAdapter mAdapter;
private RefreshLoadMoreListener mRefreshLoadMoreListner;//下拉和加载更多监听
private ItemClickListener itemClickListener;//item点击监听
private LinearLayout mExceptView;
private LinearLayout mLoadingView;
private boolean hasMore = false;//是否还有更多数据加载
private boolean canMore = true;//是否可以加载更多
private boolean isCanRefresh = true;//是否可以刷新更多
private boolean isRefresh = false;//正在刷新
private boolean isLoadMore = false;//正在加载更多
private LoadMoreWrapper mLoadMoreWrapper;//为了实现加载更多footview private ImageView exceptIv;//异常图片控件
private TextView exceptTv;//异常内容文本控件 private ProgressBar loadingIv;//正在加载图片控件
private TextView loadingTv;//正在加载文本控件
private RecyclerView.ItemAnimator itemAnimator; public MyRecycleView(Context context) {
super(context);
} public MyRecycleView(Context context, AttributeSet attrs) {
super(context, attrs);
LinearLayout rootLl = new LinearLayout(context);
rootLl.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
mLoadingView = initLoadingView(context);
mLoadingView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
mExceptView = initExceptionView(context);
mExceptView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
mExceptView.setVisibility(View.GONE);
swipeRfl = new SwipeRefreshLayout(context);
swipeRfl.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
swipeRfl.setColorSchemeResources(android.R.color.holo_blue_light,
android.R.color.holo_red_light, android.R.color.holo_orange_light);
FrameLayout bootLl = new FrameLayout(context);
bootLl.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
recyclerView = new RecyclerView(context);
recyclerView.setVerticalScrollBarEnabled(true);
recyclerView.setHorizontalScrollBarEnabled(true);
if (itemAnimator!=null)
recyclerView.setItemAnimator(itemAnimator);
else {
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
recyclerView.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
bootLl.addView(mLoadingView);
bootLl.addView(recyclerView);
bootLl.addView(mExceptView);
swipeRfl.addView(bootLl);
rootLl.addView(swipeRfl);
this.addView(rootLl);
/**
* 下拉至顶部刷新监听
*/
mRefreshListener = new SwipeRefreshLayout.OnRefreshListener() { @Override
public void onRefresh() {
if (!isRefresh && !isLoadMore) {
isRefresh = true;
refresh();
}
}
};
swipeRfl.setOnRefreshListener(mRefreshListener);
recyclerView.setHasFixedSize(true);//不是瀑布流这个将可以优化性能
} public MyRecycleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} /**
* 错误提示界面初始化
*
* @param context
* @return
*/
private LinearLayout initExceptionView(Context context) {
LinearLayout rootLl = (LinearLayout) View.inflate(context, R.layout.mycycleview_err, null);
exceptIv = (ImageView) rootLl.findViewById(R.id.myrecle_img);
exceptIv.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// 点击图片刷新
if (!isRefresh) {
swipeRfl.setRefreshing(true);
isRefresh = true;
refresh();
}
}
});
exceptTv = (TextView) rootLl.findViewById(R.id.myrecle_msg);
return rootLl;
} /**
* 初始化正在加载页面
*
* @param context
* @return
*/
private LinearLayout initLoadingView(Context context) {
LinearLayout rootLl = (LinearLayout) View.inflate(context, R.layout.mycycleview_firstload, null);
loadingIv = (ProgressBar) rootLl.findViewById(R.id.myrecle_load_progress);
loadingTv = (TextView) rootLl.findViewById(R.id.myrecle_load_msg);
return rootLl;
} /**
* drawableId 错误提示图片
* exceptStr 错误提示语
*/
public void customExceptView(int drawableId, String exceptStr) {
recyclerView.setVisibility(View.INVISIBLE);
mExceptView.setVisibility(View.VISIBLE);
mLoadingView.setVisibility(View.INVISIBLE);
exceptIv.setImageResource(drawableId);
exceptTv.setText(exceptStr);
swipeRfl.setEnabled(false);//出现错误之后,将设定无法下拉,运用点击图片进行刷新
} /**
* drawableId 正在加载提示图片
* exceptStr 正在加载提示语
*/
public void customLoadView(String exceptStr) {
recyclerView.setVisibility(View.INVISIBLE);
mLoadingView.setVisibility(View.VISIBLE);
mExceptView.setVisibility(View.INVISIBLE);
loadingTv.setText(exceptStr);
swipeRfl.setEnabled(false);
} public void scrollToTop() {
recyclerView.scrollToPosition(0);
} public void setAdapter(CommonAdapter adapter) {
if (adapter != null) {
this.mAdapter = adapter;
if (canMore) {//是否可以加载更多
mLoadMoreWrapper = new LoadMoreWrapper(mAdapter);
mLoadMoreWrapper.setLoadMoreView(R.layout.mycycle_foot_default_loading);
mLoadMoreWrapper.setOnLoadMoreListener(new LoadMoreWrapper.OnLoadMoreListener() {
@Override
public void onLoadMoreRequested() {
/**
* 无论水平还是垂直
*/
if (hasMore && !isLoadMore && !isRefresh && canMore) {
isLoadMore = true;
loadMore();
}
}
}); recyclerView.setAdapter(mLoadMoreWrapper);
} else {
recyclerView.setAdapter(mAdapter);
} mAdapter.setOnItemClickListener(new CommonAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
if (itemClickListener != null)
itemClickListener.onClick(view, holder, position);
} @Override
public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {
if (itemClickListener != null)
itemClickListener.onLongClick(view, holder, position);
return true;
}
});
}
} private void setHasMore(boolean enable) {
this.hasMore = enable;
if (mLoadMoreWrapper!=null)
mLoadMoreWrapper.setFootCanLoad(hasMore);
} /* public boolean isHasMore() {
return hasMore;
} public boolean isCanMore() {
return canMore;
}*/ public boolean isCanMore() {
return canMore;
} public void setCanMore(boolean canMore) {
this.canMore = canMore;
} public void setPullRefreshEnable(boolean enable) {
isCanRefresh = enable;
swipeRfl.setEnabled(enable);
} public boolean getPullRefreshEnable() {
return swipeRfl.isEnabled();
} public void loadMore() {
if (mRefreshLoadMoreListner != null && hasMore && canMore) {
mRefreshLoadMoreListner.onLoadMore();
}
} /**
* 加载更多完毕,为防止频繁网络请求,isLoadMore为false才可再次请求更多数据
*/
public void setLoadMoreCompleted() {
isLoadMore = false;
} public void stopRefresh() {
isRefresh = false;
swipeRfl.setRefreshing(false);
if (isCanRefresh) swipeRfl.setEnabled(true);
} public void setRefreshLoadMoreListener(RefreshLoadMoreListener listener) {
mRefreshLoadMoreListner = listener;
} public void setOnItemClickListener(ItemClickListener listener) {
itemClickListener = listener;
} /**
* 刷新动作,用于请求网络数据
*/
public void refresh() {
swipeRfl.setRefreshing(true);
mExceptView.setVisibility(View.INVISIBLE);
if (mRefreshLoadMoreListner != null) {
mRefreshLoadMoreListner.onRefresh();
}
} public void notifyDataSetChanged() {
//firstload布局只能出现一次,所以这里判断如果显示,就隐藏
if (mLoadingView.getVisibility() == View.VISIBLE) {
recyclerView.setVisibility(View.VISIBLE);
mExceptView.setVisibility(View.INVISIBLE);
mLoadingView.setVisibility(View.INVISIBLE);
}
if (mLoadMoreWrapper != null)
mLoadMoreWrapper.notifyDataSetChanged();
else
mAdapter.notifyDataSetChanged();
} /**
* 第一次自动加载,不与无数据用同样布局是因为,这里要有动画效果,所以单独一个布局
*/
public void firstLoadingView(String exceptStr) { customLoadView(exceptStr);
isRefresh = true;
if (mRefreshLoadMoreListner != null) {
mRefreshLoadMoreListner.onRefresh();
}
} /**
* 获取刷新数据以后的处理
* @param actAllList
* @param tmp
* @param drawableId 当没有数据时提示图片
* @param msg 没有数据时提示语
*/
public void setDateRefresh(List<T> actAllList, List<T> tmp,int drawableId,String msg) {
actAllList.clear();
stopRefresh();//如果刷新则停止刷新
if (tmp==null || tmp.isEmpty()) {
customExceptView(drawableId, msg);
setHasMore(false);
} else {
recyclerView.setVisibility(View.VISIBLE);
setHasMore(true);
actAllList.addAll(tmp);
}
notifyDataSetChanged();//刷新完毕
} /**
* 获取加载更多数据的处理
*
* @param actAllList
* @param tmpLoadmore
*/
public void setDateLoadMore(List<T> actAllList, List<T> tmpLoadmore) {
if (tmpLoadmore==null|| tmpLoadmore.isEmpty()) {
setHasMore(false);//如果没有更多数据则设置不可加载更多
setLoadMoreCompleted();//加载完毕
stopRefresh();//如果刷新则停止刷新
return;
}
setHasMore(true);
actAllList.addAll(tmpLoadmore);
setLoadMoreCompleted();//加载完毕
notifyDataSetChanged();//加载更多完毕
stopRefresh();//如果刷新则停止刷新
} /**
* 刷新数据失败
*
* @param darwable
* @param msg
*/
public void setDateRefreshErr(int darwable, String msg) {
stopRefresh();//如果刷新则停止刷新
customExceptView(darwable, msg);
} public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
recyclerView.setLayoutManager(layoutManager);
} public void addItemDecoration(RecyclerView.ItemDecoration div) {
recyclerView.addItemDecoration(div);
} /**
* 设置item动画效果
* @param defaultItemAnimator
*/
public void setItemAnimator(RecyclerView.ItemAnimator defaultItemAnimator) {
this.itemAnimator=defaultItemAnimator;
recyclerView.setItemAnimator(itemAnimator);
} /**
* 下拉刷新和自动加载监听
*/
public interface RefreshLoadMoreListener {
public void onRefresh(); public void onLoadMore();
} public interface ItemClickListener {
public void onClick(View view, RecyclerView.ViewHolder holder, int position); public void onLongClick(View view, RecyclerView.ViewHolder holder, int position);
} }

MyRecycleView带有上拉加载更多的更多相关文章

  1. 原生js移动端touch事件实现上拉加载更多

    大家都知道jQuery里没有touch事件,所以在移动端使用原生js实现上拉加载效果还是很不错的,闲话不多说,代码如下: //获取要操作的元素 var objSection = document.ge ...

  2. H5基于iScroll实现下拉刷新,上拉加载更多

    前言 前一段有个手机端的项目需要用到下拉刷新和上拉加载更多的效果,脑海里第一反映就是微博那种效果,刚开始的理解有些偏差,以为下拉也是追加数据,上拉也是追加数据,后请教同事后发现其实下拉只是刷新最新数据 ...

  3. 常见开发需求之angular上拉加载更多

    需求   移动端使用angular实现上拉加载更多的条目,这个需求比较常见,网上的插件改动起来比较麻烦,不如自己写一个最适合,以前有同事写了一个,奈何bug太多,后来改分页了,我们产品说什么都让做,没 ...

  4. ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多

    ListView实现Item上下拖动交换位置  并且实现下拉刷新  上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...

  5. ionic 上拉加载更多&瀑布流加载&滚动到底部加载更多 主意事项

    首先下拉刷新的代码是这样的,标红的地方为关键代码 <html> <head> <meta charset="utf-8"> <meta n ...

  6. android ListView下拉刷新 上拉加载更多

    背景 最近在公司的项目中要使用到ListView的下拉刷新和上拉加载更多(貌似现在是个项目就有这个功能!哈哈),其实这个东西GitHub上很多,但是我感觉那些框架太大,而且我这个项目只用到了ListV ...

  7. Android 上拉加载更多功能

    前几天看了github上面的例子,参照它的实现,自己又稍微改了一点,往项目里面增加了一个上拉加载更多功能.具体的实现如下: 首先要重写ListView: import android.content. ...

  8. android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

    Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableL ...

  9. RecyclerView实例-实现可下拉刷新上拉加载更多并可切换线性流和瀑布流模式(1)

    摘要 最近项目有个列表页需要实现线性列表和瀑布流展示的切换,首先我想到的就是上 [RecyclerView],他本身已经很好的提供了三种布局方式,只是简单做个切换应该是很简单的事情,如果要用Recyc ...

随机推荐

  1. 栈--数据结构与算法Javascript描述(4)

    栈 Stack 概念 栈是一种高效的数据结构,数据只能在栈顶添加或者删除,所以这样的操作很快,而且容易实现.栈的使用遍布程序语言的方方面面,从表达式求值到处理函数调用. 栈是一种特殊的列表,栈内的元素 ...

  2. 使wlr写cnblog的博客-2 设置cnblog帐号

    ref:http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html   使用: 打开Windows Live Writer,第一次 ...

  3. 05,Python网络爬虫之三种数据解析方式

    回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据 ...

  4. sprintf()函数使用异常

    调试STM32F103,比如如下代码:使用springf函数,这个函数是把最后两个参数先格式化成字符串 ,输出到ERROR_STRING,如果他们合并的长度大于30会出现深情况? ] sprintf( ...

  5. nginx配置及HTTPS配置示例

    一.nginx简单配置示例 user www www; worker_processes ; #error_log logs/error.log; #error_log logs/error.log ...

  6. 项目中使用ECharts插件实现统计功能

    一.前端界面 // 界面中定义一个div,放图表 <div id="box" style="width: 600px;height:400px;padding: 1 ...

  7. 第一天docker入门

    [01 入门] docker 最核心为三部分组成 镜像,仓库和容器 镜像:一个只读的模板 仓库:代码仓库,镜像的集合 容器:镜像的实例化进程 我们可以这样理解 容器就是一个沙箱,docker利用容器运 ...

  8. JS 如何获取radio或者checkbox选中后的值

    废话不多说,直接上代码: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  9. 孤荷凌寒自学python第二十六天python的time模块的相关方法

    孤荷凌寒自学python第二十六天python的time模块的相关方法 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 要使用time模块的相关方法,必须在文件顶端引用: import tim ...

  10. Metadata 的概念

    https://www.ibm.com/developerworks/cn/cloud/library/1509_liukg_openstackmeta/ http://mathslinux.org/ ...