RecyclerView-------之GridView模式加载更多
随着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模式加载更多的更多相关文章
- Android5.0新特性:RecyclerView实现上拉加载更多
RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势.下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基 ...
- Recyclerview 实现上拉加载更多
LinearLayoutManager layoutManager; layoutManager = new LinearLayoutManager(getActivity()); layoutMan ...
- RecyclerView下拉刷新上拉加载更多
现在Android里都建议用RecyclerView代替ListView和GridView,所以下拉刷新和上拉加载更多也需要实现.下拉刷新可以用SwipeRefreshLayout 包裹Recycle ...
- 实现上拉加载更多的SwipeRefreshLayout
转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...
- RecyclerView实例-实现可下拉刷新上拉加载更多并可切换线性流和瀑布流模式(1)
摘要 最近项目有个列表页需要实现线性列表和瀑布流展示的切换,首先我想到的就是上 [RecyclerView],他本身已经很好的提供了三种布局方式,只是简单做个切换应该是很简单的事情,如果要用Recyc ...
- ScrollView嵌套ListView嵌套GridView的上下拉以及加载更多
ScrollView 效果 ScrollView 说明 一个ScrollView 嵌套ListView 嵌套GridView的上拉加载更多,下拉刷新的demo. 主要是重写了GridView和Lsit ...
- Android RecyclerView 瀑布流滑动到最后自动加载更多
mRecycleView.setOnScrollListener(new RecyclerView.OnScrollListener(){ //用来标记是否正在向最后一个滑动,既是否向下滑动 bool ...
- RecyclerView 判断滑到底部 顶部 预加载 更多 分页 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果演示
实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性.网格.瀑布流效果演示 效果预览 实例APP 小米应用商店 使用方法 build.gradle文件 dependenc ...
随机推荐
- ArrayList源码解析(四)
这篇文章主要看ArrayList的Iterator和ListIterator的实现. 1.Iterator和类Itr 当我们调用iterator方法时返回一个Iterator. /** * Retur ...
- JSONP不支持循环调用
问题描述 在jquery或zepto下,循环调用同一个jsonp ;i<;i++){ $.ajax({ url:'https://m.suning.com/authStatus?callback ...
- PHP cURL的详细使用手册
PHP cURL的详细使用手册 PHP cURL可以帮助我们简单有效地去抓取网页内容,帮助我们方便的实现抓取功能.本文主要介绍了PHP cURL的使用方法. AD:2013云计算架构师峰会课程资料下载 ...
- Scrapy的debug方式
Scrapy不方便调试,但是为了深入学习框架内部的一些原理,有时候仅仅依靠日志是不够的.下面提供一种scrapy的debug方式 demo直接用来自官方例子来演示:https://github.com ...
- 【初码干货】记一次分布式B站爬虫任务系统的完整设计和实施
[初码文章推荐] 程序员的自我修养 Azure系列文章 阿里云系列文章 爬虫系列文章 [初码产品推荐] AlphaMS开发模式 闪送达城市中央厨房 今天带来一个有意思的东西-分布式B站爬虫任务系统 这 ...
- a标签点击之后有个虚线边框,怎么去掉
1.行内处理方式1 <a hidefocus="true" href="#"></a> 2.行内处理方式2,让a标签获得焦点就失去焦点, ...
- Page directive must not have multiple occurrences of pageencoding
一个jsp文件中不能同时出现两个 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #932192 } pageE ...
- CSS3学习系列之选择器(三)
E:enabled伪类选择器和E:disabled伪类选择器 E:enabled伪类选择器用来指定元素处于可用状态的样式. E:disabled伪类选择器用来指定当元素处于不可用状态时的样式. 当一个 ...
- 用javascript实现java的Map
function Map(){ var obj={}; //空的容器 //put方法 this.put=function(key,value){ obj[key]=value; //把键值绑定到obj ...
- 动态读取文件持续显示在UI上
private void DisplayLogInfo(FileInfo _LastFile) { if (_LastFile != null) { StreamReader sr = null; t ...