use of com.alibaba.android.vlayout.OrientationHelperEx in project vlayout by alibaba.
the class FixLayoutHelper method doMeasureAndLayout.
private void doMeasureAndLayout(View view, LayoutManagerHelper helper) {
if (view == null || helper == null) {
return;
}
final VirtualLayoutManager.LayoutParams params = (VirtualLayoutManager.LayoutParams) view.getLayoutParams();
final OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
if (layoutInVertical) {
final int widthSpec = helper.getChildMeasureSpec(helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), params.width >= 0 ? params.width : ((mSketchMeasure && layoutInVertical) ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT), false);
int heightSpec;
if (!Float.isNaN(params.mAspectRatio) && params.mAspectRatio > 0) {
heightSpec = helper.getChildMeasureSpec(helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), (int) (View.MeasureSpec.getSize(widthSpec) / params.mAspectRatio + 0.5f), false);
} else if (!Float.isNaN(mAspectRatio) && mAspectRatio > 0) {
heightSpec = helper.getChildMeasureSpec(helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), (int) (View.MeasureSpec.getSize(widthSpec) / mAspectRatio + 0.5f), false);
} else {
heightSpec = helper.getChildMeasureSpec(helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), params.height >= 0 ? params.height : ((mSketchMeasure && !layoutInVertical) ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT), false);
}
// do measurement
helper.measureChildWithMargins(view, widthSpec, heightSpec);
} else {
final int heightSpec = helper.getChildMeasureSpec(helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), params.height >= 0 ? params.height : ((mSketchMeasure && !layoutInVertical) ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT), false);
int widthSpec;
if (!Float.isNaN(params.mAspectRatio) && params.mAspectRatio > 0) {
widthSpec = helper.getChildMeasureSpec(helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), (int) (View.MeasureSpec.getSize(heightSpec) * params.mAspectRatio + 0.5f), false);
} else if (!Float.isNaN(mAspectRatio) && mAspectRatio > 0) {
widthSpec = helper.getChildMeasureSpec(helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), (int) (View.MeasureSpec.getSize(heightSpec) * mAspectRatio + 0.5f), false);
} else {
widthSpec = helper.getChildMeasureSpec(helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), params.width >= 0 ? params.width : ((mSketchMeasure && layoutInVertical) ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT), false);
}
// do measurement
helper.measureChildWithMargins(view, widthSpec, heightSpec);
}
int left, top, right, bottom;
if (mAlignType == TOP_RIGHT) {
top = helper.getPaddingTop() + mY + mAdjuster.top;
right = helper.getContentWidth() - helper.getPaddingRight() - mX - mAdjuster.right;
left = right - params.leftMargin - params.rightMargin - view.getMeasuredWidth();
bottom = top + params.topMargin + params.bottomMargin + view.getMeasuredHeight();
} else if (mAlignType == BOTTOM_LEFT) {
left = helper.getPaddingLeft() + mX + mAdjuster.left;
bottom = helper.getContentHeight() - helper.getPaddingBottom() - mY - mAdjuster.bottom;
right = left + params.leftMargin + params.rightMargin + view.getMeasuredWidth();
top = bottom - view.getMeasuredHeight() - params.topMargin - params.bottomMargin;
} else if (mAlignType == BOTTOM_RIGHT) {
right = helper.getContentWidth() - helper.getPaddingRight() - mX - mAdjuster.right;
bottom = helper.getContentHeight() - helper.getPaddingBottom() - mY - mAdjuster.bottom;
left = right - params.leftMargin - params.rightMargin - view.getMeasuredWidth();
top = bottom - view.getMeasuredHeight() - params.topMargin - params.bottomMargin;
} else {
// TOP_LEFT
left = helper.getPaddingLeft() + mX + mAdjuster.left;
top = helper.getPaddingTop() + mY + mAdjuster.top;
right = left + (layoutInVertical ? orientationHelper.getDecoratedMeasurementInOther(view) : orientationHelper.getDecoratedMeasurement(view));
bottom = top + (layoutInVertical ? orientationHelper.getDecoratedMeasurement(view) : orientationHelper.getDecoratedMeasurementInOther(view));
}
layoutChildWithMargin(view, left, top, right, bottom, helper);
}
use of com.alibaba.android.vlayout.OrientationHelperEx 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 com.alibaba.android.vlayout.OrientationHelperEx in project vlayout by alibaba.
the class OnePlusNLayoutHelper method layoutViews.
@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;
}
final OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
final boolean layoutStart = layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START;
final int parentWidth = helper.getContentWidth();
final int parentHeight = helper.getContentHeight();
final int parentHPadding = helper.getPaddingLeft() + helper.getPaddingRight() + getHorizontalMargin() + getHorizontalPadding();
final int parentVPadding = helper.getPaddingTop() + helper.getPaddingBottom() + getVerticalMargin() + getVerticalPadding();
final int currentPosition = layoutState.getCurrentPosition();
if (hasHeader && currentPosition == getRange().getLower()) {
View header = nextView(recycler, layoutState, helper, result);
int headerConsumed = handleHeader(header, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
if (header != null) {
int left = 0, right = 0, top = 0, bottom = 0;
if (layoutInVertical) {
if (layoutStart) {
bottom = layoutState.getOffset();
top = bottom - headerConsumed;
} else {
top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginTop + mPaddingTop);
bottom = top + headerConsumed;
}
left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft;
right = left + orientationHelper.getDecoratedMeasurementInOther(header);
} else {
if (layoutStart) {
right = layoutState.getOffset();
left = right - headerConsumed;
} else {
left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginLeft + mPaddingLeft);
right = left + headerConsumed;
}
top = helper.getPaddingTop() + mMarginTop + mPaddingTop;
bottom = top + orientationHelper.getDecoratedMeasurementInOther(header);
}
layoutChildWithMargin(header, left, top, right, bottom, helper);
}
result.mConsumed = headerConsumed;
handleStateOnResult(result, header);
} else if (hasFooter && currentPosition == getRange().getUpper()) {
View footer = nextView(recycler, layoutState, helper, result);
int footerConsumed = handleFooter(footer, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
if (footer != null) {
int left = 0, right = 0, top = 0, bottom = 0;
if (layoutInVertical) {
if (layoutStart) {
// TODO margin overlap
bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom);
top = bottom - footerConsumed;
} else {
top = layoutState.getOffset();
bottom = top + footerConsumed;
}
left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft;
right = left + orientationHelper.getDecoratedMeasurementInOther(footer);
} else {
if (layoutStart) {
// TODO margin overlap
right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight);
left = right - footerConsumed;
} else {
left = layoutState.getOffset();
right = left + footerConsumed;
}
top = helper.getPaddingTop() + mMarginTop + mPaddingTop;
bottom = top + orientationHelper.getDecoratedMeasurementInOther(footer);
}
layoutChildWithMargin(footer, left, top, right, bottom, helper);
}
result.mConsumed = footerConsumed;
handleStateOnResult(result, footer);
} else {
int contentCount = getItemCount() - (hasHeader ? 1 : 0) - (hasFooter ? 1 : 0);
if (mChildrenViews == null || mChildrenViews.length != contentCount) {
mChildrenViews = new View[contentCount];
}
int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper);
if (count == 0 || count < contentCount) {
return;
}
int mainConsumed = 0;
if (contentCount == 1) {
mainConsumed = handleOne(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
} else if (contentCount == 2) {
mainConsumed = handleTwo(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
} else if (contentCount == 3) {
mainConsumed = handleThree(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
} else if (contentCount == 4) {
mainConsumed = handleFour(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
} else if (contentCount == 5) {
mainConsumed = handleFive(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding);
}
result.mConsumed = mainConsumed;
Arrays.fill(mChildrenViews, null);
}
}
use of com.alibaba.android.vlayout.OrientationHelperEx in project vlayout by alibaba.
the class OnePlusNLayoutHelper method handleFooter.
private int handleFooter(View footer, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) {
if (footer == null) {
return 0;
}
OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
final VirtualLayoutManager.LayoutParams lp = (LayoutParams) footer.getLayoutParams();
// fill width
int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical);
int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical);
helper.measureChildWithMargins(footer, widthSpec, heightSpec);
return orientationHelper.getDecoratedMeasurement(footer);
}
use of com.alibaba.android.vlayout.OrientationHelperEx in project vlayout by alibaba.
the class OnePlusNLayoutHelper method handleTwo.
private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) {
int mainConsumed = 0;
OrientationHelperEx orientationHelper = helper.getMainOrientationHelper();
final View child1 = mChildrenViews[0];
final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams();
final View child2 = mChildrenViews[1];
final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams();
final float weight1 = getViewMainWeight(0);
final float weight2 = getViewMainWeight(1);
if (layoutInVertical) {
if (!Float.isNaN(mAspectRatio)) {
lp1.height = lp2.height = (int) ((parentWidth - parentHPadding) / mAspectRatio);
}
lp2.topMargin = lp1.topMargin;
lp2.bottomMargin = lp1.bottomMargin;
int availableSpace = parentWidth - parentHPadding - lp1.leftMargin - lp1.rightMargin - lp2.leftMargin - lp2.rightMargin;
int width1 = Float.isNaN(weight1) ? (int) (availableSpace / 2.0f + 0.5f) : (int) (availableSpace * weight1 / 100 + 0.5f);
int width2 = Float.isNaN(weight2) ? (availableSpace - width1) : (int) (availableSpace * weight2 / 100 + 0.5f);
helper.measureChildWithMargins(child1, MeasureSpec.makeMeasureSpec(width1 + lp1.leftMargin + lp1.rightMargin, MeasureSpec.EXACTLY), helper.getChildMeasureSpec(helper.getContentHeight(), lp1.height, true));
helper.measureChildWithMargins(child2, MeasureSpec.makeMeasureSpec(width2 + lp2.leftMargin + lp2.rightMargin, MeasureSpec.EXACTLY), helper.getChildMeasureSpec(helper.getContentHeight(), lp2.height, true));
mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), orientationHelper.getDecoratedMeasurement(child2));
calculateRect(mainConsumed, mAreaRect, layoutState, helper);
int right1 = mAreaRect.left + orientationHelper.getDecoratedMeasurementInOther(child1);
layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper);
layoutChildWithMargin(child2, right1, mAreaRect.top, right1 + orientationHelper.getDecoratedMeasurementInOther(child2), mAreaRect.bottom, helper);
mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom);
} else {
if (!Float.isNaN(mAspectRatio)) {
lp1.width = lp2.width = (int) ((parentHeight - parentVPadding) * mAspectRatio);
}
int availableSpace = parentHeight - parentVPadding - lp1.topMargin - lp1.bottomMargin - lp2.topMargin - lp2.bottomMargin;
int height1 = Float.isNaN(weight1) ? (int) (availableSpace / 2.0f + 0.5f) : (int) (availableSpace * weight1 / 100 + 0.5f);
int height2 = Float.isNaN(weight2) ? (int) (availableSpace - height1) : (int) (availableSpace * weight2 / 100 + 0.5f);
helper.measureChildWithMargins(child1, helper.getChildMeasureSpec(helper.getContentWidth(), lp1.width, true), MeasureSpec.makeMeasureSpec(height1 + lp1.topMargin + lp1.bottomMargin, MeasureSpec.EXACTLY));
int width = child1.getMeasuredWidth();
helper.measureChildWithMargins(child2, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height2 + lp2.topMargin + lp2.bottomMargin, MeasureSpec.EXACTLY));
mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), orientationHelper.getDecoratedMeasurement(child2));
calculateRect(mainConsumed, mAreaRect, layoutState, helper);
int bottom1 = mAreaRect.top + orientationHelper.getDecoratedMeasurementInOther(child1);
layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, mAreaRect.right, bottom1, helper);
layoutChildWithMargin(child2, mAreaRect.left, bottom1, mAreaRect.right, bottom1 + orientationHelper.getDecoratedMeasurementInOther(child2), helper);
mainConsumed = mAreaRect.right - mAreaRect.left + (hasHeader ? 0 : mMarginLeft + mPaddingRight) + (hasFooter ? 0 : mMarginRight + mPaddingRight);
}
handleStateOnResult(result, mChildrenViews);
return mainConsumed;
}
Aggregations