最近項目上需要實現(xiàn)一個搜索歷史的一個布局越走,由于每次的搜索內(nèi)容文本長度完全不同,因此布局的時候不可能采用Linear或Grid布局磅废,需要自定義一種布局
RrecycleView的布局都是代理給RecyclerView.LayoutManager去處理的骑冗,因此自定義的布局管理器繼承自此類,然后重寫onLayoutChildren方法去計算布局戒突,詳細代碼如下
package com.demo;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class AutoLineFeedLayoutManager extends RecyclerView.LayoutManager {
public AutoLineFeedLayoutManager() {
setAutoMeasureEnabled(true);//layoutmanager必須調(diào)用此方法設為true才能在onMesure時自動布局
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(
RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
int curLineWidth = 0, curLineTop = 0;//curLineWidth 累加item布局時的x軸偏移curLineTop 累加item布局時的x軸偏移
int lastLineMaxHeight = 0;
for (int i = 0; i < getItemCount(); i++) {
View view = recycler.getViewForPosition(i);
//獲取每個item的布局參數(shù),計算每個item的占用位置時需要加上margin
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view) + params.leftMargin + params.rightMargin;
int height = getDecoratedMeasuredHeight(view) + params.topMargin + params.bottomMargin;
curLineWidth += width;//累加當前行已有item的寬度
if (curLineWidth <= getWidth()) {//如果累加的寬度小于等于RecyclerView的寬度描睦,不需要換行
layoutDecorated(view, curLineWidth - width + params.leftMargin, curLineTop + params.topMargin, curLineWidth - params.rightMargin, curLineTop + height - params.bottomMargin);//布局item的真實位置
//比較當前行多有item的最大高度膊存,用于換行后計算item在y軸上的偏移量
lastLineMaxHeight = Math.max(lastLineMaxHeight, height);
} else {//換行
curLineWidth = width;
if (lastLineMaxHeight == 0) {
lastLineMaxHeight = height;
}
//記錄當前行top
curLineTop += lastLineMaxHeight;
layoutDecorated(view, params.leftMargin, curLineTop + params.topMargin, width - params.rightMargin, curLineTop + height - params.bottomMargin);
lastLineMaxHeight = height;
}
}
}
}
寫好LayoutManager之后使用時只需要new一個此Manager然后設置給RecyclerView即可,如下
RecyclerView recycler = (RecyclerView)findViewById(R.id.recycler);
recycler.setLayoutManager(new AutoLineFeedLayoutManager());
如上代碼設置后酌摇,item布局時會盡量布局在一行膝舅,當此行顯示不下時自動換行,效果如下圖
圖片.png