AutoSize
xmutzlq opened this issue · 1 comments
xmutzlq commented
@OverRide
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
// 如果是 preLayout 则不重新布局
if (state.isPreLayout() || !state.didStructureChange()) {
return;
}
if (getItemCount() == 0) {
removeAndRecycleAllViews(recycler);
// 页面变化回调
setPageCount(0);
setPageIndex(0, false);
return;
} else {
setPageCount(getTotalPageCount());
setPageIndex(getPageIndexByOffset(), false);
}
// 计算页面数量
int mPageCount = getItemCount() / mOnePageSize;
if (getItemCount() % mOnePageSize != 0) {
mPageCount++;
}
// 计算可以滚动的最大数值,并对滚动距离进行修正
if (canScrollHorizontally()) {
mMaxScrollX = (mPageCount - 1) * getUsableWidth();
mMaxScrollY = 0;
if (mOffsetX > mMaxScrollX) {
mOffsetX = mMaxScrollX;
}
} else {
mMaxScrollX = 0;
mMaxScrollY = (mPageCount - 1) * getUsableHeight();
if (mOffsetY > mMaxScrollY) {
mOffsetY = mMaxScrollY;
}
}
// 接口回调
// setPageCount(mPageCount);
// setPageIndex(mCurrentPageIndex, false);
if (mItemWidth <= 0) {
mItemWidth = getUsableWidth() / mColumns;
}
if (mItemHeight <= 0) {
mItemHeight = getUsableHeight() / mRows;
}
mWidthUsed = getUsableWidth() - mItemWidth;
mHeightUsed = getUsableHeight() - mItemHeight;
// 预存储两页的View显示区域
for (int i = 0; i < mOnePageSize * 2; i++) {
getItemFrameByPosition(i);
}
if (mOffsetX == 0 && mOffsetY == 0) {
// 预存储View
for (int i = 0; i < mOnePageSize; i++) {
if (i >= getItemCount()) break; // 防止数据过少时导致数组越界异常
View view = recycler.getViewForPosition(i);
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams();
lp.width = ScreenUtils.getScreenWidth() / mColumns - (lp.leftMargin + lp.rightMargin) / 2;
addView(view);
measureChildWithMargins(view, mWidthUsed, mHeightUsed);
}
}
// 回收和填充布局
recycleAndFillItems(recycler, state, true);
}
@OverRide
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(recycler, state, widthMeasureSpec, heightMeasureSpec);
int widthsize = View.MeasureSpec.getSize(widthMeasureSpec); //取出宽度的确切数值
int widthmode = View.MeasureSpec.getMode(widthMeasureSpec); //取出宽度的测量模式
// 将 wrap_content 转换为 match_parent
if (widthmode != EXACTLY && widthsize > 0) {
widthmode = EXACTLY;
}
final int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
final int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);
int height = 0;
//自适应高度
for (int i = 0; i < getItemCount(); i++) {
try {
measureScrapChild(recycler, i,
widthMeasureSpec,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
if (i == 0) {
height = mMeasuredDimension[1];
}
}
switch (heightMode) {
case EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(View.MeasureSpec.makeMeasureSpec(widthsize, widthmode), height - 200);
}
private int[] mMeasuredDimension = new int[2];
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(widthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
}
xmutzlq commented
性能不是很好!