publicclassFlowLayoutManagerextendsRecyclerView.LayoutManager{
privatestaticfinalStringTAG=FlowLayoutManager.class.getSimpleName();
privateintwidth, height;
privateintleft, top, right;
//最大容器的宽度
privateintusedMaxWidth;
//竖直方向上的偏移量
privateintverticalScrollOffset=0;
//计算显示的内容的高度
privateinttotalHeight=0;
privateRowrow=newRow();
publicFlowLayoutManager() {
setAutoMeasureEnabled(true);//此处重点注意,,无需自己去测量
}
publicclassItem{
intuseHeight;
Viewview;
publicItem(intuseHeight,Viewview) {
this.useHeight=useHeight;
this.view=view;
}
}
publicclassRow{
publicvoidsetCuTop(floatcuTop) {
this.cuTop=cuTop;
}
publicvoidsetMaxHeight(floatmaxHeight) {
this.maxHeight=maxHeight;
}
floatcuTop;
floatmaxHeight;
Listviews=newArrayList<>();
publicvoidaddViews(Itemview) {
views.add(view);
}
publicvoidclear() {
cuTop=0;
maxHeight=0;
views.clear();
}
}
@Override
publicRecyclerView.LayoutParamsgenerateDefaultLayoutParams() {
returnnewRecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
publicvoidonLayoutChildren(RecyclerView.Recyclerrecycler,RecyclerView.Statestate) {
if(state.isPreLayout()) {
return;
}
detachAndScrapAttachedViews(recycler);
width=getWidth();
height=getHeight();
totalHeight=0;
left=getPaddingLeft();
right=getPaddingRight();
top=getPaddingTop();
usedMaxWidth=width-left-right;
intcuLineTop=top;
//当前行使用的宽度
intcuLineWidth=0;
intitemLeft;
intitemTop;
intmaxHeightItem=0;
row.clear();
for(inti=0; i
ViewchildAt=recycler.getViewForPosition(i);
addView(childAt);
if(View.GONE==childAt.getVisibility()) {
continue;
}
measureChildWithMargins(childAt,0,0);
intchildWidth=getDecoratedMeasuredWidth(childAt);
intchildHeight=getDecoratedMeasuredHeight(childAt);
Log.d(TAG,"childHeight:"+childHeight);
intchildUseWidth=childWidth;
intchildUseHeight=childHeight;
//如果加上当前的item还小于最大的宽度的话
if(cuLineWidth+childUseWidth<=usedMaxWidth) {
itemLeft=left+cuLineWidth;
itemTop=cuLineTop;
layoutDecoratedWithMargins(childAt, itemLeft, itemTop, itemLeft+childWidth, itemTop+childHeight);
cuLineWidth+=childUseWidth;
maxHeightItem=Math.max(maxHeightItem, childUseHeight);
row.addViews(newItem(childUseHeight, childAt));
row.setCuTop(cuLineTop);
row.setMaxHeight(maxHeightItem);
}else{
//换行
formatAboveRow();
cuLineTop+=maxHeightItem;
totalHeight+=maxHeightItem;
itemTop=cuLineTop;
itemLeft=left;
layoutDecoratedWithMargins(childAt, itemLeft, itemTop, itemLeft+childWidth, itemTop+childHeight);
cuLineWidth=childUseWidth;
maxHeightItem=childUseHeight;
row.addViews(newItem(childUseHeight, childAt));
row.setCuTop(cuLineTop);
row.setMaxHeight(maxHeightItem);
}
//不要忘了最后一行进行刷新下布局
if(i==getItemCount()-1) {
formatAboveRow();
totalHeight+=maxHeightItem;
}
}
totalHeight=Math.max(totalHeight, getVerticalSpace());
}
/**
* 计算每一行没有居中的viewgroup,让居中显示
*/
privatevoidformatAboveRow() {
Listviews=row.views;
for(inti=0; i
Viewview=views.get(i).view;
if(views.get(i).useHeight
layoutDecoratedWithMargins(view, getDecoratedLeft(view),
(int) (row.cuTop+(row.maxHeight-getDecoratedMeasuredHeight(view))/2), getDecoratedRight(view),
(int) (row.cuTop+(row.maxHeight-getDecoratedMeasuredHeight(view))/2+getDecoratedMeasuredHeight(view)));
}
}
row.clear();
}
/**
* 竖直方向需要滑动的条件
*
* @return
*/
@Override
publicbooleancanScrollVertically() {
returntrue;
}
//监听竖直方向滑动的偏移量
@Override
publicintscrollVerticallyBy(intdy,RecyclerView.Recyclerrecycler,
RecyclerView.Statestate) {
//实际要滑动的距离
inttravel=dy;
//如果滑动到最顶部
if(verticalScrollOffset+dy<0) {//限制滑动到顶部之后,不让继续向上滑动了
travel=-verticalScrollOffset;//verticalScrollOffset=0
}elseif(verticalScrollOffset+dy>totalHeight-getVerticalSpace()) {//如果滑动到最底部
travel=totalHeight-getVerticalSpace()-verticalScrollOffset;//verticalScrollOffset=totalHeight - getVerticalSpace()
}
//将竖直方向的偏移量+travel
verticalScrollOffset+=travel;
//平移容器内的item
offsetChildrenVertical(-travel);
returntravel;
}
privateintgetVerticalSpace() {
returnheight-getPaddingBottom()-getPaddingTop();
}
}