@Override
public void onBindViewHolder(DemoViewHolder holder, int position) {
holder.itemView.getLayoutParams().width = (self.getDemoModels().get(position).getPreferWidth());
holder.itemView.getLayoutParams().height = (self.getDemoModels().get(position).getPreferHeight());
holder.setDelegate(self);
holder.reload(self);
}
接下来我们开始创建一个自定义的CustomLayoutManager,先预设一下想要的效果,为了简单实现,笔者自定义的CustomLayoutManager会进行斜线布局,即从容器左上角开始放置item,下一个item的左上角坐标对应上一个item的右下角坐标。
public class CustomLayoutManager extends RecyclerView.LayoutManager {
/** Convenience Var to call this */
final CustomLayoutManager self = this;
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler); // 分离所有的itemView
int offsetX = 0;
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View scrap = recycler.getViewForPosition(i); // 根据position获取一个碎片view,可以从回收的view中获取,也可能新构造一个
addView(scrap);
measureChildWithMargins(scrap, 0, 0); // 计算此碎片view包含边距的尺寸
int width = getDecoratedMeasuredWidth(scrap); // 获取此碎片view包含边距和装饰的宽度width
int height = getDecoratedMeasuredHeight(scrap); // 获取此碎片view包含边距和装饰的高度height
layoutDecorated(scrap, offsetX , offsetY, offsetX + width, offsetY + height); // Important!布局到RecyclerView容器中,所有的计算都是为了得出任意position的item的边界来布局
offsetX += width;
offsetY += height;
}
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
device-2016-01-08-104053.png
没有实现重用
无法滑动
基本原理是这样的:
在每一次重新对item布局时(item信息改变时),计算每个item的坐标尺寸记录下来,如果一个item的坐标尺寸与当前显示区域矩阵相交就展示这个item,否则回收这个item。
显示区域有滑动偏移量和容器大小决定,每次滑动时都要进行重新布局。
感谢阅读。