GcsSloop / GcsSloop/pager-layoutmanager

AutoSize

Open
#21 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.1k
Forks
181
PR merge metrics
No merged PRs in 30d

Description

@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);
}
}

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the onMeasure, onLayoutChildren, and measureScrapChild methods included in the issue, then review Android RecyclerView LayoutManager measurement behavior. Reproduce the current sizing behavior and clarify the expected auto-size dimensions before deciding what tests or other files should define done.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.