LineaLayoutManager 设置间距比较简单就不再说了
final int divider = AndroidUtil.dpToPx(10, mContext);
gridItemDecoration = new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
final GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) view.getLayoutParams();
final int spanCount = layoutManager.getSpanCount();
int layoutPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
if (lp.getSpanSize() != spanCount) {
//左边间距
if (layoutPosition % 2 == 1) {
outRect.left = divider / 2;
outRect.right = divider;
} else {
outRect.left = divider;
outRect.right = divider / 2;
}
}
outRect.top = divider;
}
};
recyclerview.addItemDecoration(gridItemDecoration);
以上的代码对应下图
注意:间距是计算在itemview之中的
像常见的九宫格的话,我最开始想到的实现方式是这样的
这种方式是有问题的,原因还是注意:间距是计算在itemview之中的,因为每个条目的大小是相等的,左右两个条目减去边距就会缩小图片的尺寸了,那就必须要一行三个,横向间距+图片大小都相等 一共4个间距,那么每个条目的横向间距总值应为4/3*间距即(1,1/3) (2/3,2/3) (1/3,1)
//每个条目的偏移距离
int eachWidth = (spanCount + 1) * divider / spanCount;
outRect.left = (spanCount-layoutPosition%spanCount)/spanCount*divider;
outRect.right = eachWidth-outRect.left;
注意:以上计算的偏移距离为左右有间距的,若左右无间距,只有中间有间距
int eachWidth = (spanCount - 1) * divider / spanCount;
计算左右间距就是数学问题了
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//判断若为banner类型,占满一行
if (bbsHomeAdapter.getItemViewType(position) == 0) {
return 2;
}else{
return 1;
}
}
});
StaggeredGridLayoutManager通过layoutposition设置会错乱,改成StaggeredGridLayoutManager.layoutParams.getSpanIndex()就好了
RecyclerView.ItemDecoration gridItemDecoration = new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//不为banner类型
if (bbsHomeAdapter.getItemViewType(parent.getChildAdapterPosition(view)) != 0) {
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
int spanIndex = layoutParams.getSpanIndex();
outRect.top = divider;
if (spanIndex == 0) {
// left
outRect.left = divider;
outRect.right = divider / 2;
} else{
outRect.right = divider;
outRect.left = divider / 2;
}
}
}
};
recyclerview.addItemDecoration(gridItemDecoration);
@Override
public void onViewAttachedToWindow(BaseHolder holder) {
super.onViewAttachedToWindow(holder);
int index = holder.getLayoutPosition();
//判断若为banner类型,占满一行
if (getItemViewType(index) == 0) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams p =
(StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
}
}
1.条目闪动
staggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
2.下拉一段距离第一行条目距顶部有间距(此解决方法未必有效)
rvContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
// 滑动停止,刷新布局与分割线
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
((StaggeredGridLayoutManager) recyclerView.getLayoutManager()).invalidateSpanAssignments();
recyclerView.invalidateItemDecorations();
}
}
}
});
3.滑动卡顿
卡顿的原因是由于要加载图片完成后,根据bitmap的宽高比设置给imageview对应的高度
没有太好的办法,让后台返回图片尺寸,直接设置给imageview,这种方法效果是最好的,可还要考虑后台不一定返回的情况,就需要自己按原样请求了,只是请求成功计算出imageview高度保存一下,以后的滑动就不会每次请求了,只是第一次卡顿了
4.瀑布流中imageview设置了scaletype为centerCrop,刷新后,同一张图可能会被多次裁剪放大中心部分
百度了半天没解决,google检索结果第一个就搜到了
参考:https://github.com/bumptech/glide/issues/1497
加上.dontTransform() 取消图片变化效果
Glide.with(mContext).load(url).dontTransform().into(ivImage);