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 ...
随机推荐
- countDownLatch和cyclicBarrier
< Effecit In Java >说过,从java 1.5发现版本开始, 就不建议使用wait和notify,它们使用比较困难,可以使用更高级并发工具来替代. 图一所说的同步器是指那些 ...
- Deep Learning in R
Introduction Deep learning is a recent trend in machine learning that models highly non-linear repre ...
- The dplyr package has been updated with new data manipulation commands for filters, joins and set operations.(转)
dplyr 0.4.0 January 9, 2015 in Uncategorized I’m very pleased to announce that dplyr 0.4.0 is now av ...
- 默认路由、RIPv2、OSPF、EIGRP配置(全网全通)
1:默认路由 遇到问题:给r2配置向右的单项默认路由,通过PC1去ping主机PC2,一直显示Request timed out, 解决方法:r2配置如下: r2(config)#ip route 0 ...
- 一天搞定HTML----标签类型与类型转换05
标签类型: 标签只有两类:行内元素和块元素 行内元素:内容撑开宽高 块元素:默认独占一行 注意: 在使用display时,会遇到一种inline-block类型的标签.这种标签不属于标签的分类. 1. ...
- python requests get/post
基本Get请求: #-*- coding:utf-8 -*- import requests url = 'http://www.baidu.com' r = requests.get(url) pr ...
- 如何实现windows命令提示符的tab补全
1:使用win+r打开 运行 控制台 2:输入 regedit 打开注册表 3:进入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\Co ...
- cpp(第十七章)
1.baseic_ostream<charT,traits>& write(const char_type *s,streamsize n),cout.write()第一个参数提供 ...
- 什么时候该选用Xamarin?
现在开发app也好,桌面程序也好,有很多不同的技术可以选择.那么,什么时候应该选用Xamarin呢? 5 questions to consider before choosing Xamarin 1 ...
- 用html5调取谷歌地图获取位置
function getmap(){ if(!navigator.geolocation) throw "Geolocation not supported"; var image ...