随着RecyclerView的出现,Listview、GridView的使用率相对有些减少,废话不多说,先看一下效果:

代码如下:

1.自定义的RecyclerView(根据自己的需要)

public class CallbkRecyclerView extends RecyclerView {
private OnReachBottomListener onReachBottomListener;
private boolean isInTheBottom = false;
private int reachBottomRow = 1;
private List<OnScrollListener> mScrollListeners;
public CallbkRecyclerView(Context context) {
super(context);
}
public CallbkRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
} public CallbkRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void onScrolled(int dx, int dy) {
if (onReachBottomListener != null) {
LayoutManager layoutManager = getLayoutManager();
if (layoutManager == null) { //it maybe unnecessary
throw new RuntimeException("LayoutManager is null,Please check it!");
}
Adapter adapter = getAdapter();
if (adapter == null) { //it maybe unnecessary
throw new RuntimeException("Adapter is null,Please check it!");
}
boolean isReachBottom = false;
//is GridLayoutManager
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
int rowCount = adapter.getItemCount() / gridLayoutManager.getSpanCount();
int lastVisibleRowPosition = gridLayoutManager.findLastVisibleItemPosition() / gridLayoutManager.getSpanCount();
isReachBottom = (lastVisibleRowPosition >= rowCount - reachBottomRow);
}
//is LinearLayoutManager
else if (layoutManager instanceof LinearLayoutManager) {
int lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
int rowCount = adapter.getItemCount();
if (reachBottomRow > rowCount)
reachBottomRow = 1;
isReachBottom = (lastVisibleItemPosition >= rowCount - reachBottomRow);
}
//is StaggeredGridLayoutManager
else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
int spanCount = staggeredGridLayoutManager.getSpanCount();
int[] into = new int[spanCount];
int[] eachSpanListVisibleItemPosition = staggeredGridLayoutManager.findLastVisibleItemPositions(into);
for (int i = 0; i < spanCount; i++) {
if (eachSpanListVisibleItemPosition[i] > adapter.getItemCount() - reachBottomRow * spanCount) {
isReachBottom = true;
break;
}
}
}
if (!isReachBottom) {
isInTheBottom = false;
} else if (!isInTheBottom) {
onReachBottomListener.onReachBottom();
isInTheBottom = true;
Log.d("RBCallbkRecyclerView", "onReachBottom");
}
}
}
public void setReachBottomRow(int reachBottomRow) {
if (reachBottomRow < 1)
reachBottomRow = 1;
this.reachBottomRow = reachBottomRow;
}
public interface OnReachBottomListener {
void onReachBottom();
} public void setOnReachBottomListener(OnReachBottomListener onReachBottomListener) {
this.onReachBottomListener = onReachBottomListener;
}
//public void addOnScrollListener(OnScrollListener listener){
// if(mScrollListeners==null){
// mScrollListeners=new ArrayList<OnScrollListener>();
// }
// mScrollListeners.add(listener);
//}
}
2.自定义GridLayoutManager(同样根据需要自定义)
public class FullyGridLayoutManager extends GridLayoutManager {
private int mwidth = 0;
private int mheight = 0; public FullyGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
} public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
} private int[] mMeasuredDimension = new int[2]; public int getMwidth() {
return mwidth;
} public void setMwidth(int mwidth) {
this.mwidth = mwidth;
} public int getMheight() {
return mheight;
} public void setMheight(int mheight) {
this.mheight = mheight;
} @Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0;
int height = 0;
int count = getItemCount();
int span = getSpanCount();
for (int i = 0; i < count; i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension); if (getOrientation() == HORIZONTAL) {
if (i % span == 0) {
width = width + mMeasuredDimension[0];
}
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
if (i % span == 0) {
height = height + mMeasuredDimension[1];
}
if (i == 0) {
width = mMeasuredDimension[0];
}
}
} switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
} switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMheight(height);
setMwidth(width);
setMeasuredDimension(width, height);
} private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
if (position < getItemCount()) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3.
public class DividerItemDecoration extends RecyclerView.ItemDecoration{

    private static final int[] ATTRS = new int[] { android.R.attr.listDivider };
private Drawable mDivider; public DividerItemDecoration(Context context)
{
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
} @Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
{ drawHorizontal(c, parent);
drawVertical(c, parent); }
private int getSpanCount(RecyclerView parent)
{
// 列数
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{ spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
}
return spanCount;
} public void drawHorizontal(Canvas c, RecyclerView parent)
{
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++)
{
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawVertical(Canvas c, RecyclerView parent)
{
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++)
{
final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
} private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL)
{
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else
{
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且纵向滚动
if (orientation == StaggeredGridLayoutManager.VERTICAL)
{
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount)
return true;
} else
// StaggeredGridLayoutManager 且横向滚动
{
// 如果是最后一行,则不需要绘制底部
if ((pos + 1) % spanCount == 0)
{
return true;
}
}
}
return false;
} public void getItemOffsets(Rect outRect, int itemPosition,
RecyclerView parent)
{
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
{
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight());
}
}
}
4.主页面
public class MainActivity extends AppCompatActivity {

    private CallbkRecyclerView recyclerView;
private List<String> list;
private HomeAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); recyclerView = (CallbkRecyclerView) findViewById(R.id.id_recyclerview);
list=new ArrayList<>();
recyclerView.setLayoutManager(new FullyGridLayoutManager(this, 2));
recyclerView.addItemDecoration(new DividerItemDecoration(this)); for(int i=0;i<20;i++){
list.add("item"+i);
}
adapter=new HomeAdapter(this,list);
recyclerView.setAdapter(adapter);
adapter.setLoadCallback(new HomeAdapter.ILoadCallback() {
@Override
public void onLoad() {
indateMore();
}
});
}
private void indateMore() {
List<String> listDte=new ArrayList<>();
for(int i=0;i<10;i++){
list.add("NewItem"+i);
}
adapter.addData(listDte);
list.addAll(listDte);
}
}

RecyclerView-------之GridView模式加载更多的更多相关文章

  1. Android5.0新特性:RecyclerView实现上拉加载更多

    RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势.下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基 ...

  2. Recyclerview 实现上拉加载更多

    LinearLayoutManager layoutManager; layoutManager = new LinearLayoutManager(getActivity()); layoutMan ...

  3. RecyclerView下拉刷新上拉加载更多

    现在Android里都建议用RecyclerView代替ListView和GridView,所以下拉刷新和上拉加载更多也需要实现.下拉刷新可以用SwipeRefreshLayout 包裹Recycle ...

  4. 实现上拉加载更多的SwipeRefreshLayout

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...

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

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

  6. ScrollView嵌套ListView嵌套GridView的上下拉以及加载更多

    ScrollView 效果 ScrollView 说明 一个ScrollView 嵌套ListView 嵌套GridView的上拉加载更多,下拉刷新的demo. 主要是重写了GridView和Lsit ...

  7. Android RecyclerView 瀑布流滑动到最后自动加载更多

    mRecycleView.setOnScrollListener(new RecyclerView.OnScrollListener(){ //用来标记是否正在向最后一个滑动,既是否向下滑动 bool ...

  8. RecyclerView 判断滑到底部 顶部 预加载 更多 分页 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. 实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果演示

    实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性.网格.瀑布流效果演示 效果预览 实例APP 小米应用商店 使用方法 build.gradle文件 dependenc ...

随机推荐

  1. Linux盘符绑定槽位

    服务器下的硬盘主有机械硬盘.固态硬盘以及raid阵列,通常内核分配盘符的顺序是/dev/sda./dev/sdb- -.在系统启动过程中,内核会按照扫描到硬盘的顺序分配盘符(先分配直通的,再分配阵列) ...

  2. 从零开始——PowerShell应用入门(全例子入门讲解)

    学习一门技术,不止要会,还要善用,例子就是带你快速入门的最佳利器.本文就是要用例子,不,大量的例子来带你走进PowerShell应用世界. 本文主要介绍一些PowerShell入门的基础知识,对技术小 ...

  3. Windows 7 蓝屏代码大全 & 蓝屏全攻略

    关于Windows 7.Vista等系统的蓝屏,之前软媒在Win7之家和Vista之家都有很多文章讨论过,但是都是筛选的常见的一些问题,今天这个文章是个大全,希望大家看着别头痛,文章收藏下来以后待查即 ...

  4. Myeclipse 配置多个tomcat

    1.首先准备多个tomcat 命名为: tomcat-8087  tomcat-8088 tomcat-8089     2.修改对应的server.xml ①:修改关闭时端口,分别设为 8005 8 ...

  5. 关于 vue-cli v2.8.2

    我在撰写<Vue2实践揭秘>时采用的 vue-cli 版本是 v2.5.1,由于实体书的出版周期比电子书的要长,所以到全书出版vue-cli已经更新到 v2.8.2 了,我在书中曾经对 v ...

  6. html打造动画【系列1】- 萌萌的大白

    每个人心中都有一个暖暖的大白,blingbling的大眼睛~软软的肚子~宽厚的肩膀~善良的心肠~如果可以,我愿意沦陷在大白的肚子里永远不出来,哈哈~毛球要失宠咯~ 哈哈哈 每个人都是独立的个体,大白也 ...

  7. 织梦CMS去广告方法 for DedeCMS V5.7

    DedeCms 5.7新版发布,下来上传至服务器安装完毕,点击进入后台登陆界面,怎么多了广告链,而且登陆界面也变了,以前可不带这样的啊.按步骤一步一步来去版权再去广告吧. 一,去处后台登陆页login ...

  8. HTTP协议入门

    1.概述 (1)HTTP是应用层协议,是从Web服务器传输超文本到本地浏览器的传送协议,端口号为80.(2)默认情况下HTTP使用TCP,但是也可以基于以后存在的其他可靠传输协议.由于UDP无法提供可 ...

  9. C# 计时器写法

        刚才一个交流群里有人问计时器怎么写,正好我也不太熟,就写了个demo,和大家分享一下这个是参考师傅的写的! 计时器有好多种写法,这里给大家推荐一个性能比较好的,用dispatchertimer ...

  10. MVC中控制器当中需要绑定SelectList,也就是所谓的DropDownList

    ViewData["moduleList"] = new SelectList(new El_Basic_ModuleInfo().Rows().AsEnumerable(), & ...