use of android.support.v7.widget.OrientationHelper in project vlayout by alibaba.
the class StaggeredGridLayoutHelper method isRecyclable.
@Override
public boolean isRecyclable(int childPos, int startIndex, int endIndex, LayoutManagerHelper helper, boolean fromStart) {
// startIndex == endIndex already be ignored in VirtualLayoutManager.recycleChildren
final boolean recyclable = super.isRecyclable(childPos, startIndex, endIndex, helper, fromStart);
if (recyclable) {
View child = helper.findViewByPosition(childPos);
if (child != null) {
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
LayoutParams lp = (LayoutParams) child.getLayoutParams();
int position = lp.getViewPosition();
if (helper.getReverseLayout()) {
if (fromStart) {
// recycle from end
Span span = findSpan(position, child, true);
if (span != null) {
span.popEnd(orientationHelper);
}
} else {
// recycle from start
Span span = findSpan(position, child, false);
if (span != null) {
span.popStart(orientationHelper);
}
}
} else {
if (fromStart) {
// recycle from start
Span span = findSpan(position, child, true);
if (span != null) {
span.popStart(orientationHelper);
}
} else {
// recycle from end
Span span = findSpan(position, child, false);
if (span != null) {
span.popEnd(orientationHelper);
}
}
}
}
}
return recyclable;
}
use of android.support.v7.widget.OrientationHelper in project vlayout by alibaba.
the class StaggeredGridLayoutHelper method layoutViews.
@Override
public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) {
if (isOutOfRange(layoutState.getCurrentPosition())) {
return;
}
ensureLanes();
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
final OrientationHelper secondaryOrientationHelper = helper.getSecondaryOrientationHelper();
mRemainingSpans.set(0, mNumLanes, true);
final int targetLine;
final int recycleLine;
// Line of the furthest row.
if (layoutState.getLayoutDirection() == LAYOUT_END) {
// ignore padding for recycler
recycleLine = layoutState.getOffset() + layoutState.getAvailable();
targetLine = recycleLine + layoutState.getExtra() + orientationHelper.getEndPadding();
} else {
// LAYOUT_START
// ignore padding for recycler
recycleLine = layoutState.getOffset() - layoutState.getAvailable();
targetLine = recycleLine - layoutState.getExtra() - orientationHelper.getStartAfterPadding();
}
updateAllRemainingSpans(layoutState.getLayoutDirection(), targetLine, orientationHelper);
final int defaultNewViewLine = layoutState.getOffset();
while (layoutState.hasMore(state) && !mRemainingSpans.isEmpty() && !isOutOfRange(layoutState.getCurrentPosition())) {
boolean isStartLine = false, isEndLine = false;
View view = layoutState.next(recycler);
if (view == null)
break;
VirtualLayoutManager.LayoutParams lp = (VirtualLayoutManager.LayoutParams) view.getLayoutParams();
// find the span to put the view
final int position = lp.getViewPosition();
final int spanIndex = mLazySpanLookup.getSpan(position);
Span currentSpan;
boolean assignSpan = spanIndex == INVALID_SPAN_ID;
if (assignSpan) {
currentSpan = getNextSpan(defaultNewViewLine, layoutState, helper);
mLazySpanLookup.setSpan(position, currentSpan);
} else {
currentSpan = mSpans[spanIndex];
}
// handle margin for start/end line
isStartLine = position - getRange().getLower() < mNumLanes;
isEndLine = getRange().getUpper() - position - 1 < mNumLanes;
helper.addChildView(layoutState, view);
if (layoutInVertical) {
int widthSpec = helper.getChildMeasureSpec(mColLength, lp.width, false);
int heightSpec = helper.getChildMeasureSpec(orientationHelper.getTotalSpace(), Float.isNaN(lp.mAspectRatio) ? lp.height : (int) (View.MeasureSpec.getSize(widthSpec) / lp.mAspectRatio + 0.5f), true);
helper.measureChild(view, widthSpec, heightSpec);
} else {
int heightSpec = helper.getChildMeasureSpec(mColLength, lp.height, false);
int widthSpec = helper.getChildMeasureSpec(orientationHelper.getTotalSpace(), Float.isNaN(lp.mAspectRatio) ? lp.width : (int) (View.MeasureSpec.getSize(heightSpec) * lp.mAspectRatio + 0.5f), true);
helper.measureChild(view, widthSpec, heightSpec);
}
int start;
int end;
if (layoutState.getLayoutDirection() == LAYOUT_END) {
start = currentSpan.getEndLine(defaultNewViewLine, orientationHelper);
if (isStartLine)
start += layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft;
else
start += (layoutInVertical ? mVGap : mHGap);
end = start + orientationHelper.getDecoratedMeasurement(view);
} else {
if (isEndLine)
end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? mMarginBottom + mPaddingRight : mMarginRight + mPaddingRight);
else
end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? mVGap : mHGap);
start = end - orientationHelper.getDecoratedMeasurement(view);
}
// lp.mSpan = currentSpan;
if (layoutState.getLayoutDirection() == LAYOUT_END) {
currentSpan.appendToSpan(view, orientationHelper);
} else {
currentSpan.prependToSpan(view, orientationHelper);
}
// left, right in vertical layout
int otherStart = ((currentSpan.mIndex == mNumLanes - 1) ? currentSpan.mIndex * (mColLength + mEachGap) - mEachGap + mLastGap : currentSpan.mIndex * (mColLength + mEachGap)) + secondaryOrientationHelper.getStartAfterPadding();
if (layoutInVertical) {
otherStart += mMarginLeft + mPaddingLeft;
} else {
otherStart += mMarginTop + mPaddingTop;
}
int otherEnd = otherStart + orientationHelper.getDecoratedMeasurementInOther(view);
if (layoutInVertical) {
layoutChild(view, otherStart, start, otherEnd, end, helper);
} else {
layoutChild(view, start, otherStart, end, otherEnd, helper);
}
updateRemainingSpans(currentSpan, layoutState.getLayoutDirection(), targetLine, orientationHelper);
recycle(recycler, layoutState, currentSpan, recycleLine, helper);
handleStateOnResult(result, view);
}
if (isOutOfRange(layoutState.getCurrentPosition())) {
// TODO: how to retain gap
if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) {
for (Span span : mSpans) {
if (span.mCachedStart != INVALID_LINE) {
span.mLastEdgeStart = span.mCachedStart;
}
}
} else {
for (Span span : mSpans) {
if (span.mCachedEnd != INVALID_LINE) {
span.mLastEdgeEnd = span.mCachedEnd;
}
}
}
}
if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) {
if (!isOutOfRange(layoutState.getCurrentPosition()) && layoutState.hasMore(state)) {
final int maxStart = getMaxStart(orientationHelper.getStartAfterPadding(), orientationHelper);
result.mConsumed = layoutState.getOffset() - maxStart;
} else {
final int minStart = getMinStart(orientationHelper.getEndAfterPadding(), orientationHelper);
result.mConsumed = layoutState.getOffset() - minStart + (layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft);
}
} else {
if (!isOutOfRange(layoutState.getCurrentPosition()) && layoutState.hasMore(state)) {
final int minEnd = getMinEnd(orientationHelper.getEndAfterPadding(), orientationHelper);
result.mConsumed = minEnd - layoutState.getOffset();
} else {
final int maxEnd = getMaxEnd(orientationHelper.getEndAfterPadding(), orientationHelper);
result.mConsumed = maxEnd - layoutState.getOffset() + (layoutInVertical ? mMarginBottom + mPaddingBottom : mMarginRight + mPaddingRight);
}
}
}
use of android.support.v7.widget.OrientationHelper in project vlayout by alibaba.
the class StaggeredGridLayoutHelper method checkAnchorInfo.
@Override
public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) {
super.checkAnchorInfo(state, anchorInfo, helper);
ensureLanes();
final Range<Integer> range = getRange();
if (anchorInfo.layoutFromEnd) {
if (anchorInfo.position < range.getLower() + mNumLanes - 1) {
anchorInfo.position = Math.min(range.getLower() + mNumLanes - 1, range.getUpper());
}
} else {
if (anchorInfo.position > range.getUpper() - (mNumLanes - 1)) {
anchorInfo.position = Math.max(range.getLower(), range.getUpper() - (mNumLanes - 1));
}
}
View reference = helper.findViewByPosition(anchorInfo.position);
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
int mainGap = layoutInVertical ? mVGap : mHGap;
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
if (reference == null) {
for (Span span : mSpans) {
span.clear();
span.setLine(anchorInfo.coordinate);
}
} else {
int anchorPos = anchorInfo.layoutFromEnd ? Integer.MIN_VALUE : Integer.MAX_VALUE;
for (Span span : mSpans) {
if (!span.mViews.isEmpty()) {
if (anchorInfo.layoutFromEnd) {
View view = span.mViews.get(span.mViews.size() - 1);
anchorPos = Math.max(anchorPos, helper.getPosition(view));
} else {
View view = span.mViews.get(0);
anchorPos = Math.min(anchorPos, helper.getPosition(view));
}
}
}
int offset = INVALID_OFFSET;
if (!isOutOfRange(anchorPos)) {
boolean isStartLine = anchorPos == range.getLower();
View view = helper.findViewByPosition(anchorPos);
if (view != null) {
if (anchorInfo.layoutFromEnd) {
anchorInfo.position = anchorPos;
final int endRef = orientationHelper.getDecoratedEnd(reference);
if (endRef < anchorInfo.coordinate) {
offset = anchorInfo.coordinate - endRef;
offset += (isStartLine ? 0 : mainGap);
anchorInfo.coordinate = orientationHelper.getDecoratedEnd(view) + offset;
} else {
offset = (isStartLine ? 0 : mainGap);
anchorInfo.coordinate = orientationHelper.getDecoratedEnd(view) + offset;
}
} else {
anchorInfo.position = anchorPos;
final int startRef = orientationHelper.getDecoratedStart(reference);
if (startRef > anchorInfo.coordinate) {
// move align up
offset = anchorInfo.coordinate - startRef;
offset -= (isStartLine ? 0 : mainGap);
anchorInfo.coordinate = orientationHelper.getDecoratedStart(view) + offset;
} else {
offset = -(isStartLine ? 0 : mainGap);
anchorInfo.coordinate = orientationHelper.getDecoratedStart(view) + offset;
}
}
}
}
for (Span span : mSpans) {
span.cacheReferenceLineAndClear(helper.getReverseLayout() ^ anchorInfo.layoutFromEnd, offset, orientationHelper);
}
}
}
Aggregations