use of android.support.v7.app.ActionBar.LayoutParams in project vlayout by alibaba.
the class LinearLayoutHelper method layoutViews.
/**
* In {@link LinearLayoutHelper}, each iteration only consume one item,
* so it can let parent LayoutManager to decide whether the next item is in the range of this helper
*/
@Override
public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state, VirtualLayoutManager.LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) {
// reach the end of this layout
if (isOutOfRange(layoutState.getCurrentPosition())) {
return;
}
int currentPosition = layoutState.getCurrentPosition();
// find corresponding layout container
View view = nextView(recycler, layoutState, helper, result);
if (view == null) {
return;
}
final boolean isOverLapMargin = helper.isEnableMarginOverLap();
VirtualLayoutManager.LayoutParams params = (VirtualLayoutManager.LayoutParams) view.getLayoutParams();
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
int startSpace = 0, endSpace = 0, gap = 0;
boolean isLayoutEnd = layoutState.getLayoutDirection() == VirtualLayoutManager.LayoutStateWrapper.LAYOUT_END;
boolean isStartLine = isLayoutEnd ? currentPosition == getRange().getLower().intValue() : currentPosition == getRange().getUpper().intValue();
boolean isEndLine = isLayoutEnd ? currentPosition == getRange().getUpper().intValue() : currentPosition == getRange().getLower().intValue();
if (isStartLine) {
startSpace = computeStartSpace(helper, layoutInVertical, isLayoutEnd, isOverLapMargin);
}
if (isEndLine) {
endSpace = computeEndSpace(helper, layoutInVertical, isLayoutEnd, isOverLapMargin);
}
if (!isStartLine) {
if (!isOverLapMargin) {
gap = mLayoutWithAnchor ? 0 : mDividerHeight;
} else {
// TODO check layout with anchor
if (isLayoutEnd) {
int marginTop = params.topMargin;
View sibling = helper.findViewByPosition(currentPosition - 1);
int lastMarginBottom = sibling != null ? ((LayoutParams) sibling.getLayoutParams()).bottomMargin : 0;
if (lastMarginBottom >= 0 && marginTop >= 0) {
gap = Math.max(lastMarginBottom, marginTop);
} else {
gap = lastMarginBottom + marginTop;
}
} else {
int marginBottom = params.bottomMargin;
View sibling = helper.findViewByPosition(currentPosition + 1);
int lastMarginTop = sibling != null ? ((LayoutParams) sibling.getLayoutParams()).topMargin : 0;
if (marginBottom >= 0 && lastMarginTop >= 0) {
gap = Math.max(marginBottom, lastMarginTop);
} else {
gap = marginBottom + lastMarginTop;
}
}
}
}
final int widthSize = helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight() - getHorizontalMargin() - getHorizontalPadding();
int widthSpec = helper.getChildMeasureSpec(widthSize, params.width, !layoutInVertical);
int heightSpec;
float viewAspectRatio = params.mAspectRatio;
if (!Float.isNaN(viewAspectRatio) && viewAspectRatio > 0) {
heightSpec = View.MeasureSpec.makeMeasureSpec((int) (widthSize / viewAspectRatio + 0.5f), View.MeasureSpec.EXACTLY);
} else if (!Float.isNaN(mAspectRatio) && mAspectRatio > 0) {
heightSpec = View.MeasureSpec.makeMeasureSpec((int) (widthSize / mAspectRatio + 0.5), View.MeasureSpec.EXACTLY);
} else {
heightSpec = helper.getChildMeasureSpec(helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom() - getVerticalMargin() - getVerticalPadding(), params.height, layoutInVertical);
}
if (!isOverLapMargin) {
helper.measureChildWithMargins(view, widthSpec, heightSpec);
} else {
helper.measureChild(view, widthSpec, heightSpec);
}
OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
result.mConsumed = orientationHelper.getDecoratedMeasurement(view) + startSpace + endSpace + gap;
int left, top, right, bottom;
if (helper.getOrientation() == VERTICAL) {
// not support RTL now
if (helper.isDoLayoutRTL()) {
right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight - mPaddingRight;
left = right - orientationHelper.getDecoratedMeasurementInOther(view);
} else {
left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft;
right = left + orientationHelper.getDecoratedMeasurementInOther(view);
}
// whether this layout pass is layout to start or to end
if (layoutState.getLayoutDirection() == VirtualLayoutManager.LayoutStateWrapper.LAYOUT_START) {
// fill start, from bottom to top
bottom = layoutState.getOffset() - startSpace - (isStartLine ? 0 : gap);
top = bottom - orientationHelper.getDecoratedMeasurement(view);
} else {
// fill end, from top to bottom
top = layoutState.getOffset() + startSpace + (isStartLine ? 0 : gap);
bottom = top + orientationHelper.getDecoratedMeasurement(view);
}
} else {
top = helper.getPaddingTop() + mMarginTop + mPaddingTop;
bottom = top + orientationHelper.getDecoratedMeasurementInOther(view);
if (layoutState.getLayoutDirection() == VirtualLayoutManager.LayoutStateWrapper.LAYOUT_START) {
// fill left, from right to left
right = layoutState.getOffset() - startSpace - (isStartLine ? 0 : gap);
left = right - orientationHelper.getDecoratedMeasurement(view);
} else {
// fill right, from left to right
left = layoutState.getOffset() + startSpace + (isStartLine ? 0 : gap);
right = left + orientationHelper.getDecoratedMeasurement(view);
}
}
// We calculate everything with View's bounding box (which includes decor and margins)
// To calculate correct layout position, we subtract margins.
layoutChildWithMargin(view, left, top, right, bottom, helper);
if (DEBUG) {
Log.d(TAG, "laid out child at position " + helper.getPosition(view) + ", with l:" + (left + params.leftMargin) + ", t:" + (top + params.topMargin) + ", r:" + (right - params.rightMargin) + ", b:" + (bottom - params.bottomMargin));
}
handleStateOnResult(result, view);
mLayoutWithAnchor = false;
}
use of android.support.v7.app.ActionBar.LayoutParams in project vlayout by alibaba.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_view);
VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// layoutManager.setReverseLayout(true);
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(10, 10, 10, 10);
}
});
final List<LayoutHelper> helpers = new LinkedList<>();
final GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4);
gridLayoutHelper.setItemCount(25);
final ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(FixLayoutHelper.TOP_RIGHT, 100, 100);
helpers.add(DefaultLayoutHelper.newHelper(7));
helpers.add(scrollFixLayoutHelper);
helpers.add(DefaultLayoutHelper.newHelper(2));
helpers.add(gridLayoutHelper);
layoutManager.setLayoutHelpers(helpers);
recyclerView.setAdapter(new VirtualLayoutAdapter(layoutManager) {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MainViewHolder(new TextView(MainActivity.this));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
VirtualLayoutManager.LayoutParams layoutParams = new VirtualLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300);
holder.itemView.setLayoutParams(layoutParams);
((TextView) holder.itemView).setText(Integer.toString(position));
if (position == 7) {
layoutParams.height = 60;
layoutParams.width = 60;
} else if (position > 35) {
layoutParams.height = 200 + (position - 30) * 100;
}
if (position > 35) {
holder.itemView.setBackgroundColor(0x66cc0000 + (position - 30) * 128);
} else if (position % 2 == 0) {
holder.itemView.setBackgroundColor(0xaa00ff00);
} else {
holder.itemView.setBackgroundColor(0xccff00ff);
}
}
@Override
public int getItemCount() {
List<LayoutHelper> helpers = getLayoutHelpers();
if (helpers == null) {
return 0;
}
int count = 0;
for (int i = 0, size = helpers.size(); i < size; i++) {
count += helpers.get(i).getItemCount();
}
return count;
}
});
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.scrollToPosition(7);
recyclerView.getAdapter().notifyDataSetChanged();
}
}, 6000);
}
use of android.support.v7.app.ActionBar.LayoutParams in project vlayout by alibaba.
the class TestActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_view);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
findViewById(R.id.jump).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText position = (EditText) findViewById(R.id.position);
if (!TextUtils.isEmpty(position.getText())) {
try {
int pos = Integer.parseInt(position.getText().toString());
recyclerView.scrollToPosition(pos);
} catch (Exception e) {
Log.e("VlayoutActivity", e.getMessage(), e);
}
}
}
});
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(4, 4, 4, 4);
}
});
recyclerView.setAdapter(new RecyclerView.Adapter() {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// TextView view = (TextView) LayoutInflater.from(TestActivity.this).inflate(R.layout.item, parent, false);
// FrameLayout frameLayout = new FrameLayout(TestActivity.this);
FrameLayout frameLayout = (FrameLayout) LayoutInflater.from(TestActivity.this).inflate(R.layout.item, parent, false);
;
// frameLayout.addView(view);
return new MainViewHolder(frameLayout);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300);
layoutParams.height = (int) (200 + (position % 15) * 10);
holder.itemView.findViewById(R.id.title).setLayoutParams(layoutParams);
if (position == 30) {
StaggeredGridLayoutManager.LayoutParams lp = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
lp.setFullSpan(true);
holder.itemView.setLayoutParams(lp);
} else {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
((StaggeredGridLayoutManager.LayoutParams) lp).setFullSpan(false);
}
}
((TextView) holder.itemView.findViewById(R.id.title)).setText(Integer.toString(position));
}
@Override
public int getItemCount() {
return 60;
}
});
}
use of android.support.v7.app.ActionBar.LayoutParams in project vlayout by alibaba.
the class AbstractFullFillLayoutHelper method getAllChildren.
protected int getAllChildren(View[] toFill, RecyclerView.Recycler recycler, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) {
final boolean layingOutInPrimaryDirection = layoutState.getItemDirection() == LayoutStateWrapper.ITEM_DIRECTION_TAIL;
int count = 0;
int firstPos = layingOutInPrimaryDirection ? getRange().getLower() : getRange().getUpper();
final int curPos = layoutState.getCurrentPosition();
if (layingOutInPrimaryDirection ? (curPos > firstPos) : (curPos > firstPos)) {
// do ugly bug fix now
Log.w(TAG, "Please handle strange order views carefully");
}
while (count < toFill.length) {
if (isOutOfRange(layoutState.getCurrentPosition()))
break;
View view = nextView(recycler, layoutState, helper, result);
if (view == null) {
break;
}
toFill[count] = view;
// normalize layout params
LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams == null) {
view.setLayoutParams(generateDefaultLayoutParams());
} else if (!checkLayoutParams(layoutParams)) {
view.setLayoutParams(generateLayoutParams(layoutParams));
}
count++;
}
if (count > 0 && !layingOutInPrimaryDirection) {
// reverse array
int s = 0, e = count - 1;
while (s < e) {
View temp = toFill[s];
toFill[s] = toFill[e];
toFill[e] = temp;
s++;
e--;
}
}
return count;
}
use of android.support.v7.app.ActionBar.LayoutParams in project vlayout by alibaba.
the class RangeGridLayoutHelper method layoutViews.
// TODO optimize this method
@Override
public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) {
// reach the end of this layout
if (isOutOfRange(layoutState.getCurrentPosition())) {
return;
}
boolean isStartLine = false, isEndLine = false;
boolean isSecondStartLine = false, isSecondEndLine = false;
final int currentPosition = layoutState.getCurrentPosition();
GridRangeStyle rangeStyle = mRangeStyle.findRangeStyleByPosition(currentPosition);
final int itemDirection = layoutState.getItemDirection();
final boolean layingOutInPrimaryDirection = itemDirection == LayoutStateWrapper.ITEM_DIRECTION_TAIL;
OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
if (layoutInVertical) {
mTotalSize = helper.getContentWidth() - helper.getPaddingRight() - helper.getPaddingLeft() - rangeStyle.getFamilyHorizontalMargin() - rangeStyle.getFamilyHorizontalPadding();
rangeStyle.mSizePerSpan = (int) ((mTotalSize - (rangeStyle.mSpanCount - 1) * rangeStyle.mHGap) * 1.0f / rangeStyle.mSpanCount + 0.5f);
} else {
mTotalSize = helper.getContentHeight() - helper.getPaddingBottom() - helper.getPaddingTop() - rangeStyle.getFamilyVerticalMargin() - rangeStyle.getFamilyVerticalPadding();
rangeStyle.mSizePerSpan = (int) ((mTotalSize - (rangeStyle.mSpanCount - 1) * rangeStyle.mVGap) * 1.0f / rangeStyle.mSpanCount + 0.5f);
}
int count = 0;
int consumedSpanCount = 0;
int remainingSpan = rangeStyle.mSpanCount;
rangeStyle.ensureSpanCount();
if (!layingOutInPrimaryDirection) {
// fill the remaining spacing this row
int itemSpanIndex = getSpanIndex(rangeStyle.mSpanSizeLookup, rangeStyle.mSpanCount, recycler, state, currentPosition);
int itemSpanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, currentPosition);
remainingSpan = itemSpanIndex + itemSpanSize;
// should find the last element of this row
if (itemSpanIndex != rangeStyle.mSpanCount - 1) {
int index = layoutState.getCurrentPosition();
int revRemainingSpan = rangeStyle.mSpanCount - remainingSpan;
while (count < rangeStyle.mSpanCount && revRemainingSpan > 0) {
// go reverse direction to find views fill current row
index -= itemDirection;
if (rangeStyle.isOutOfRange(index)) {
break;
}
final int spanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, index);
if (spanSize > rangeStyle.mSpanCount) {
throw new IllegalArgumentException("Item at position " + index + " requires " + spanSize + " spans but RangeGridLayoutHelper has only " + rangeStyle.mSpanCount + " spans.");
}
View view = layoutState.retrieve(recycler, index);
if (view == null) {
break;
}
if (!isStartLine) {
isStartLine = helper.getReverseLayout() ? index == mRangeStyle.getRange().getUpper().intValue() : index == mRangeStyle.getRange().getLower().intValue();
}
if (!isEndLine) {
isEndLine = helper.getReverseLayout() ? index == mRangeStyle.getRange().getLower().intValue() : index == mRangeStyle.getRange().getUpper().intValue();
}
revRemainingSpan -= spanSize;
if (revRemainingSpan < 0) {
break;
}
consumedSpanCount += spanSize;
rangeStyle.mSet[count] = view;
count++;
}
if (count > 0) {
// reverse array
int s = 0, e = count - 1;
while (s < e) {
View temp = rangeStyle.mSet[s];
rangeStyle.mSet[s] = rangeStyle.mSet[e];
rangeStyle.mSet[e] = temp;
s++;
e--;
}
}
}
}
while (count < rangeStyle.mSpanCount && layoutState.hasMore(state) && remainingSpan > 0) {
int pos = layoutState.getCurrentPosition();
if (rangeStyle.isOutOfRange(pos)) {
if (DEBUG) {
Log.d(TAG, "pos [" + pos + "] is out of range");
}
break;
}
final int spanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, pos);
if (spanSize > rangeStyle.mSpanCount) {
throw new IllegalArgumentException("Item at position " + pos + " requires " + spanSize + " spans but GridLayoutManager has only " + rangeStyle.mSpanCount + " spans.");
}
remainingSpan -= spanSize;
if (remainingSpan < 0) {
// item did not fit into this row or column
break;
}
if (!isStartLine) {
isStartLine = helper.getReverseLayout() ? pos == mRangeStyle.getRange().getUpper().intValue() : pos == mRangeStyle.getRange().getLower().intValue();
}
if (!isSecondStartLine) {
if (!rangeStyle.equals(mRangeStyle)) {
isSecondStartLine = helper.getReverseLayout() ? pos == rangeStyle.getRange().getUpper().intValue() : pos == rangeStyle.getRange().getLower().intValue();
}
}
if (!isEndLine) {
isEndLine = helper.getReverseLayout() ? pos == mRangeStyle.getRange().getLower().intValue() : pos == mRangeStyle.getRange().getUpper().intValue();
}
if (!isSecondEndLine) {
if (!rangeStyle.equals(mRangeStyle)) {
isSecondEndLine = helper.getReverseLayout() ? pos == rangeStyle.getRange().getLower().intValue() : pos == rangeStyle.getRange().getUpper().intValue();
if (DEBUG) {
Log.d(TAG, "isSecondEndLineLogic:" + isSecondEndLine + " helper.getReverseLayout()=" + helper.getReverseLayout() + " pos=" + pos + " rangeStyle.getRange().getLower()=" + rangeStyle.getRange().getLower() + " rangeStyle.getRange().getUpper()=" + rangeStyle.getRange().getUpper());
}
}
}
View view = layoutState.next(recycler);
if (view == null) {
break;
}
consumedSpanCount += spanSize;
rangeStyle.mSet[count] = view;
count++;
}
if (count == 0) {
return;
}
int maxSize = 0;
// we should assign spans before item decor offsets are calculated
assignSpans(rangeStyle, recycler, state, count, consumedSpanCount, layingOutInPrimaryDirection, helper);
if (remainingSpan > 0 && (count == consumedSpanCount) && rangeStyle.mIsAutoExpand) {
// autoExpand only support when each cell occupy one span.
if (layoutInVertical) {
rangeStyle.mSizePerSpan = (mTotalSize - (count - 1) * rangeStyle.mHGap) / count;
} else {
rangeStyle.mSizePerSpan = (mTotalSize - (count - 1) * rangeStyle.mVGap) / count;
}
} else if (!layingOutInPrimaryDirection && remainingSpan == 0 && (count == consumedSpanCount) && rangeStyle.mIsAutoExpand) {
// autoExpand only support when each cell occupy one span.
if (layoutInVertical) {
rangeStyle.mSizePerSpan = (mTotalSize - (count - 1) * rangeStyle.mHGap) / count;
} else {
rangeStyle.mSizePerSpan = (mTotalSize - (count - 1) * rangeStyle.mVGap) / count;
}
}
boolean weighted = false;
if (rangeStyle.mWeights != null && rangeStyle.mWeights.length > 0) {
weighted = true;
int totalSpace;
if (layoutInVertical) {
totalSpace = mTotalSize - (count - 1) * rangeStyle.mHGap;
} else {
totalSpace = mTotalSize - (count - 1) * rangeStyle.mVGap;
}
// calculate width with weight in percentage
int eqCnt = 0, remainingSpace = totalSpace;
int colCnt = (remainingSpan > 0 && rangeStyle.mIsAutoExpand) ? count : rangeStyle.mSpanCount;
for (int i = 0; i < colCnt; i++) {
if (i < rangeStyle.mWeights.length && !Float.isNaN(rangeStyle.mWeights[i]) && rangeStyle.mWeights[i] >= 0) {
float weight = rangeStyle.mWeights[i];
rangeStyle.mSpanCols[i] = (int) (weight * 1.0f / 100 * totalSpace + 0.5f);
remainingSpace -= rangeStyle.mSpanCols[i];
} else {
eqCnt++;
rangeStyle.mSpanCols[i] = -1;
}
}
if (eqCnt > 0) {
int eqLength = remainingSpace / eqCnt;
for (int i = 0; i < colCnt; i++) {
if (rangeStyle.mSpanCols[i] < 0) {
rangeStyle.mSpanCols[i] = eqLength;
}
}
}
}
for (int i = 0; i < count; i++) {
View view = rangeStyle.mSet[i];
helper.addChildView(layoutState, view, layingOutInPrimaryDirection ? -1 : 0);
int spanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, helper.getPosition(view)), spec;
if (weighted) {
final int index = rangeStyle.mSpanIndices[i];
int spanLength = 0;
for (int j = 0; j < spanSize; j++) {
spanLength += rangeStyle.mSpanCols[j + index];
}
spec = View.MeasureSpec.makeMeasureSpec(Math.max(0, spanLength), View.MeasureSpec.EXACTLY);
} else {
spec = View.MeasureSpec.makeMeasureSpec(rangeStyle.mSizePerSpan * spanSize + Math.max(0, spanSize - 1) * (layoutInVertical ? rangeStyle.mHGap : rangeStyle.mVGap), View.MeasureSpec.EXACTLY);
}
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (helper.getOrientation() == VERTICAL) {
helper.measureChildWithMargins(view, spec, getMainDirSpec(rangeStyle, lp.height, mTotalSize, View.MeasureSpec.getSize(spec), lp.mAspectRatio));
} else {
helper.measureChildWithMargins(view, getMainDirSpec(rangeStyle, lp.width, mTotalSize, View.MeasureSpec.getSize(spec), lp.mAspectRatio), View.MeasureSpec.getSize(spec));
}
final int size = orientationHelper.getDecoratedMeasurement(view);
if (size > maxSize) {
maxSize = size;
}
}
// views that did not measure the maxSize has to be re-measured
final int maxMeasureSpec = getMainDirSpec(rangeStyle, maxSize, mTotalSize, 0, Float.NaN);
for (int i = 0; i < count; i++) {
final View view = rangeStyle.mSet[i];
if (orientationHelper.getDecoratedMeasurement(view) != maxSize) {
int spanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, helper.getPosition(view)), spec;
if (weighted) {
final int index = rangeStyle.mSpanIndices[i];
int spanLength = 0;
for (int j = 0; j < spanSize; j++) {
spanLength += rangeStyle.mSpanCols[j + index];
}
spec = View.MeasureSpec.makeMeasureSpec(Math.max(0, spanLength), View.MeasureSpec.EXACTLY);
} else {
spec = View.MeasureSpec.makeMeasureSpec(rangeStyle.mSizePerSpan * spanSize + Math.max(0, spanSize - 1) * (layoutInVertical ? rangeStyle.mHGap : rangeStyle.mVGap), View.MeasureSpec.EXACTLY);
}
if (helper.getOrientation() == VERTICAL) {
helper.measureChildWithMargins(view, spec, maxMeasureSpec);
} else {
helper.measureChildWithMargins(view, maxMeasureSpec, spec);
}
}
}
int startSpace = 0, endSpace = 0;
int secondStartSpace = 0, secondEndSpace = 0;
boolean isLayoutEnd = layoutState.getLayoutDirection() == VirtualLayoutManager.LayoutStateWrapper.LAYOUT_END;
final boolean isOverLapMargin = helper.isEnableMarginOverLap();
if (isStartLine) {
startSpace = computeStartSpace(helper, layoutInVertical, isLayoutEnd, isOverLapMargin);
}
if (isSecondStartLine) {
secondStartSpace = (layoutInVertical ? rangeStyle.getMarginTop() + rangeStyle.getPaddingTop() : rangeStyle.getMarginLeft() + rangeStyle.getPaddingLeft());
}
if (isEndLine) {
endSpace = layoutInVertical ? mRangeStyle.getMarginBottom() + mRangeStyle.getPaddingBottom() : mRangeStyle.getMarginRight() + mRangeStyle.getPaddingRight();
}
if (isSecondEndLine) {
secondEndSpace = (layoutInVertical ? rangeStyle.getMarginBottom() + rangeStyle.getPaddingBottom() : rangeStyle.getMarginRight() + rangeStyle.getPaddingRight());
if (DEBUG) {
Log.d(TAG, "isSecondEndLineLogic:" + isSecondEndLine + " pos=" + currentPosition + " secondEndSpace=" + secondEndSpace);
}
}
result.mConsumed = maxSize + startSpace + endSpace + secondStartSpace + secondEndSpace;
final boolean layoutStart = layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START;
int consumedGap = 0;
if (!mLayoutWithAnchor) {
if (!layoutStart) {
if (!isStartLine) {
if (isSecondStartLine) {
consumedGap = (layoutInVertical ? rangeStyle.mParent.mVGap : rangeStyle.mParent.mHGap);
if (DEBUG) {
Log.d(TAG, "⬇ " + currentPosition + " 1 " + consumedGap + " gap");
}
} else {
consumedGap = (layoutInVertical ? rangeStyle.mVGap : rangeStyle.mHGap);
if (DEBUG) {
Log.d(TAG, "⬇ " + currentPosition + " 2 " + consumedGap + " gap");
}
}
}
} else {
if (!isEndLine) {
if (isSecondEndLine) {
consumedGap = (layoutInVertical ? rangeStyle.mParent.mVGap : rangeStyle.mParent.mHGap);
if (DEBUG) {
Log.d(TAG, "⬆ " + currentPosition + " 3 " + consumedGap + " gap");
}
} else {
consumedGap = (layoutInVertical ? rangeStyle.mVGap : rangeStyle.mHGap);
if (DEBUG) {
Log.d(TAG, "⬆ " + currentPosition + " 4 " + consumedGap + " gap");
}
}
}
}
}
result.mConsumed += consumedGap;
if (result.mConsumed <= 0) {
result.mConsumed = 0;
}
int lastUnconsumedSpace = 0;
/**
* layoutView() may be triggered by layoutManager's scrollInternalBy() or onFocusSearchFailed() or onLayoutChildren()
*
* In case of scrollInternalBy() or onFocusSearchFailed(), layoutState.isRefreshLayout() == false, and layoutState.mOffset = ChildClosestToExpose + alignOffset,
* see {@link com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx#updateLayoutStateExpose(int, int, boolean, State)},
* this means last line's layout padding or margin is not really consumed, so considering it before layout new line.
*
* In case of onLayoutChildren(), layoutState.isRefreshLayout() == true, and layoutState.mOffset = anchorInfo.mCoordinate = anchorChild.start + alignOffset,
* see {@link com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx#updateAnchorInfoForLayoutExpose(State, AnchorInfo)},
* this means last line's layout padding or margin is consumed.
*/
if (!layoutState.isRefreshLayout()) {
if (layoutStart) {
int lastLinePosition = currentPosition + 1;
if (!isOutOfRange(lastLinePosition)) {
RangeStyle<GridRangeStyle> neighbourRange = mRangeStyle.findRangeStyleByPosition(lastLinePosition);
if (neighbourRange.isFirstPosition(lastLinePosition)) {
lastUnconsumedSpace = layoutInVertical ? neighbourRange.getMarginTop() + neighbourRange.getPaddingTop() : neighbourRange.getMarginLeft() + neighbourRange.getPaddingLeft();
if (DEBUG) {
Log.d(TAG, "⬆ " + currentPosition + " 1 " + lastUnconsumedSpace + " last");
}
}
}
} else {
int lastLinePosition = currentPosition - 1;
if (!isOutOfRange(lastLinePosition)) {
RangeStyle<GridRangeStyle> neighbourRange = mRangeStyle.findRangeStyleByPosition(lastLinePosition);
if (neighbourRange.isLastPosition(lastLinePosition)) {
lastUnconsumedSpace = layoutInVertical ? neighbourRange.getMarginBottom() + neighbourRange.getPaddingBottom() : neighbourRange.getMarginRight() + neighbourRange.getPaddingRight();
if (DEBUG) {
Log.d(TAG, "⬇ " + currentPosition + " 2 " + lastUnconsumedSpace + " last");
}
}
}
}
}
if (DEBUG) {
Log.d(TAG, (layoutStart ? "⬆ " : "⬇ ") + currentPosition + " consumed " + result.mConsumed + " startSpace " + startSpace + " endSpace " + endSpace + " secondStartSpace " + secondStartSpace + " secondEndSpace " + secondEndSpace + " lastUnconsumedSpace " + lastUnconsumedSpace + " isSecondEndLine=" + isSecondEndLine);
}
int left = 0, right = 0, top = 0, bottom = 0;
if (layoutInVertical) {
if (layoutStart) {
bottom = layoutState.getOffset() - endSpace - secondEndSpace - (consumedGap) - lastUnconsumedSpace;
top = bottom - maxSize;
} else {
top = layoutState.getOffset() + startSpace + secondStartSpace + (consumedGap) + lastUnconsumedSpace;
bottom = top + maxSize;
}
} else {
if (layoutStart) {
right = layoutState.getOffset() - endSpace - (consumedGap) - lastUnconsumedSpace;
left = right - maxSize;
} else {
left = layoutState.getOffset() + startSpace + (consumedGap) + lastUnconsumedSpace;
right = left + maxSize;
}
}
for (int i = 0; i < count; i++) {
View view = rangeStyle.mSet[i];
final int index = rangeStyle.mSpanIndices[i];
LayoutParams params = (LayoutParams) view.getLayoutParams();
if (layoutInVertical) {
if (weighted) {
left = helper.getPaddingLeft() + rangeStyle.getFamilyMarginLeft() + rangeStyle.getFamilyPaddingLeft();
for (int j = 0; j < index; j++) {
left += rangeStyle.mSpanCols[j] + rangeStyle.mHGap;
}
} else {
left = helper.getPaddingLeft() + rangeStyle.getFamilyMarginLeft() + rangeStyle.getFamilyPaddingLeft() + rangeStyle.mSizePerSpan * index + index * rangeStyle.mHGap;
}
right = left + orientationHelper.getDecoratedMeasurementInOther(view);
} else {
if (weighted) {
top = helper.getPaddingTop() + rangeStyle.getFamilyMarginTop() + rangeStyle.getFamilyPaddingTop();
for (int j = 0; j < index; j++) {
top += rangeStyle.mSpanCols[j] + rangeStyle.mVGap;
}
} else {
top = helper.getPaddingTop() + rangeStyle.getFamilyMarginTop() + rangeStyle.getFamilyPaddingTop() + rangeStyle.mSizePerSpan * index + index * rangeStyle.mVGap;
}
bottom = top + orientationHelper.getDecoratedMeasurementInOther(view);
}
if (DEBUG) {
Log.d(TAG, "layout item in position: " + params.getViewPosition() + " with text with SpanIndex: " + index + " into (" + left + ", " + top + ", " + right + ", " + bottom + "), topInfo=[layoutState.getOffset()=" + layoutState.getOffset() + " startSpace=" + startSpace + " secondStartSpace=" + secondStartSpace + " consumedGap=" + consumedGap + " lastUnconsumedSpace=" + lastUnconsumedSpace + "]");
}
// We calculate everything with View's bounding box (which includes decor and margins)
// To calculate correct layout position, we subtract margins.
rangeStyle.layoutChild(view, left, top, right, bottom, helper, false);
// Consume the available space if the view is not removed OR changed
if (params.isItemRemoved() || params.isItemChanged()) {
result.mIgnoreConsumed = true;
}
result.mFocusable |= view.isFocusable();
}
mLayoutWithAnchor = false;
Arrays.fill(rangeStyle.mSet, null);
Arrays.fill(rangeStyle.mSpanIndices, 0);
Arrays.fill(rangeStyle.mSpanCols, 0);
}
Aggregations