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 ...
随机推荐
- 深入tornado中的http1connection
前言 tornado中http1connection文件的作用极其重要,他实现了http1.x协议. 本模块基于gen模块和iostream模块实现异步的处理请求或者响应. 阅读本文需要一些基础的ht ...
- WEB前端:浏览器(IE+Chrome+Firefox)常见兼容问题处理--01
兼容问题目录 1.IE6下怪异盒模型 2.IE6下最小高度问题 3.IE6下不支持1px的点线 4.IE6下内容会把父级的高度撑开 5.IE6下只支持给a标签添加伪类 6.IE67下不支持给块标签加d ...
- 排序与检索【UVa10474】Where is the Marble?
Where is the Marble? DescriptionRaju and Meena love to play with Marbles. They have got a lot of ma ...
- nodejs零基础详细教程2:模块化、fs文件操作模块、http创建服务模块
第二章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...
- Nginx实用教程(二):配置文件入门
Nginx配置文件结构 nginx配置文件由指令(directive)组成,指令分为两种形式,简单指令和区块指令. 一条简单指令由指令名.参数和结尾的分号(;)组成,例如: listen backlo ...
- 关于前后端同构,我的一点思路和心得(vue、nodejs、react、模版、amd)
最近1年多,前后端同构慢慢变成一个流行词,也许很多人还停留在前后端分离的最佳实践道路上,但实际上又有一批人已经从简单的服务端渲染走向探索最佳前后端同构方案的路上了.不过,我只是膜拜后者的过客. 虽然大 ...
- java入门学习笔记之1(类的定义,代码的编译执行)
这篇文章讲解Java代码的基本执行过程 我们先抛开各种JAVA IDE,开发工具,只使用文本编辑器,以突出最本质的东西. 在Linux环境下,我们编辑一个文件: vim HelloWorld.java ...
- WCF入门, 到创建一个简单的WCF应用程序
什么是WCF? WCF, 英文全称(windows Communication Foundation) , 即为windows通讯平台. windows想到这里大家都知道了 , WCF也正是由微软公 ...
- 使用jQuery筛选排除元素以修改指定标签的属性
简单案例: $(function(){ $("td[id][id!='']").click(function(){ //你的逻辑 }); }); 上述代码,有id且id不为空的td ...
- phpcms V9 后台验证码图片不显示
某个网站在本地运行成功,上传到服务器上后,发现后台登陆的验证码图片不显示 根据网上提供的解决方案, 网站路径变量web_path没问题 database.system的配置路径没问题 apache的G ...