use of android.support.v7.widget.RecyclerView.Recycler 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.widget.RecyclerView.Recycler in project vlayout by alibaba.
the class BaseLayoutHelper method nextView.
/**
* Retrieve next view and add it into layout, this is to make sure that view are added by order
*
* @param recycler recycler generate views
* @param layoutState current layout state
* @param helper helper to add views
* @param result chunk result to tell layoutManager whether layout process goes end
* @return next view to render, null if no more view available
*/
@Nullable
public final View nextView(RecyclerView.Recycler recycler, LayoutStateWrapper layoutState, LayoutManagerHelper helper, LayoutChunkResult result) {
View view = layoutState.next(recycler);
if (view == null) {
// no more items to layout.
if (DEBUG && !layoutState.hasScrapList()) {
throw new RuntimeException("received null view when unexpected");
}
// if there is no more views can be retrieved, this layout process is finished
result.mFinished = true;
return null;
}
helper.addChildView(layoutState, view);
return view;
}
use of android.support.v7.widget.RecyclerView.Recycler in project vlayout by alibaba.
the class StaggeredGridLayoutHelper method recycleFromEnd.
private void recycleFromEnd(RecyclerView.Recycler recycler, int line, LayoutManagerHelper helper) {
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
final int childCount = helper.getChildCount();
int i;
for (i = childCount - 1; i >= 0; i--) {
View child = helper.getChildAt(i);
if (child != null && orientationHelper.getDecoratedStart(child) > line) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
int position = lp.getViewPosition();
Span span = findSpan(position, child, false);
if (span != null) {
span.popEnd(orientationHelper);
helper.removeChildView(child);
recycler.recycleView(child);
}
} else {
// done
return;
}
}
}
use of android.support.v7.widget.RecyclerView.Recycler in project vlayout by alibaba.
the class StickyLayoutHelper 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;
}
// find view in currentPosition
View view = mFixView;
if (view == null)
view = layoutState.next(recycler);
else
layoutState.skipCurrentPosition();
if (view == null) {
result.mFinished = true;
return;
}
doMeasure(view, helper);
// do layout
final boolean layoutInVertical = helper.getOrientation() == VERTICAL;
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
result.mConsumed = orientationHelper.getDecoratedMeasurement(view);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
// Do normal measure&layout phase by default
mDoNormalHandle = true;
final int remainingSpace = layoutState.getAvailable() - result.mConsumed + layoutState.getExtra();
int left, top, right, bottom;
if (helper.getOrientation() == VERTICAL) {
// not support RTL now
if (helper.isDoLayoutRTL()) {
right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight;
left = right - orientationHelper.getDecoratedMeasurementInOther(view);
} else {
left = helper.getPaddingLeft() + mMarginLeft;
right = left + orientationHelper.getDecoratedMeasurementInOther(view);
}
// whether this layout pass is layout to start or to end
if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) {
// fill start, from bottom to top
bottom = layoutState.getOffset() - mMarginBottom;
top = layoutState.getOffset() - result.mConsumed;
} else {
// fill end, from top to bottom
if (mStickyStart) {
top = layoutState.getOffset() + mMarginTop;
bottom = layoutState.getOffset() + result.mConsumed;
} else {
bottom = orientationHelper.getEndAfterPadding() - mMarginBottom - mOffset - mAdjuster.bottom;
top = bottom - result.mConsumed;
}
}
if (helper.getReverseLayout() || !mStickyStart) {
if ((remainingSpace < (mOffset + mAdjuster.bottom) && layoutState.getItemDirection() == LayoutStateWrapper.ITEM_DIRECTION_TAIL) || (bottom > mMarginBottom + mOffset + mAdjuster.bottom)) {
mDoNormalHandle = false;
mFixView = view;
bottom = orientationHelper.getEndAfterPadding() - mMarginBottom - mOffset - mAdjuster.bottom;
top = bottom - result.mConsumed;
}
} else {
// should not use 0
if ((remainingSpace < (mOffset + mAdjuster.top) && layoutState.getItemDirection() == LayoutStateWrapper.ITEM_DIRECTION_HEAD) || (top < mMarginTop + mOffset + mAdjuster.top)) {
mDoNormalHandle = false;
mFixView = view;
top = orientationHelper.getStartAfterPadding() + mMarginTop + mOffset + mAdjuster.top;
bottom = top + result.mConsumed;
} else {
Log.i("Sticky", "remainingSpace: " + remainingSpace + " offset: " + mOffset);
}
}
} else {
top = helper.getPaddingTop();
bottom = top + orientationHelper.getDecoratedMeasurementInOther(view) + mMarginTop;
if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) {
right = layoutState.getOffset() - mMarginRight;
left = layoutState.getOffset() - result.mConsumed;
} else {
left = layoutState.getOffset() + mMarginLeft;
right = layoutState.getOffset() + result.mConsumed;
}
if (helper.getReverseLayout() || !mStickyStart) {
if (remainingSpace < mOffset + mAdjuster.right) {
mDoNormalHandle = false;
mFixView = view;
right = orientationHelper.getEndAfterPadding() - mOffset - mAdjuster.right;
left = right - result.mConsumed;
}
} else {
if (remainingSpace < mOffset + mAdjuster.left) {
mDoNormalHandle = false;
mFixView = view;
left = orientationHelper.getStartAfterPadding() + mOffset + mAdjuster.left;
right = result.mConsumed;
}
}
}
layoutChild(view, left, top, right, bottom, helper);
result.mConsumed += (layoutInVertical ? getVerticalMargin() : getHorizontalMargin());
if (state.isPreLayout()) {
mDoNormalHandle = true;
}
if (mDoNormalHandle) {
helper.addChildView(layoutState, view);
handleStateOnResult(result, view);
mFixView = null;
} else {
// result.mConsumed += mOffset;
}
}
use of android.support.v7.widget.RecyclerView.Recycler in project vlayout by alibaba.
the class StickyLayoutHelper method afterLayout.
@Override
public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state, int startPosition, int endPosition, int scrolled, LayoutManagerHelper helper) {
super.afterLayout(recycler, state, startPosition, endPosition, scrolled, helper);
// disabled if mPos is negative number
if (mPos < 0)
return;
final OrientationHelper orientationHelper = helper.getMainOrientationHelper();
// not normal flow,
if (!mDoNormalHandle && mPos >= startPosition && mPos <= endPosition) {
Log.i("TEST", "abnormal pos: " + mPos + " start: " + startPosition + " end: " + endPosition);
if (mFixView != null) {
int top, bottom;
View refer = null;
if (mStickyStart) {
for (int i = helper.getChildCount() - 1; i >= 0; i--) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos < mPos) {
// TODO: when view size is larger than totalSpace!
top = orientationHelper.getDecoratedEnd(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(pos);
if (layoutHelper instanceof MarginLayoutHelper) {
top = top + ((MarginLayoutHelper) layoutHelper).mMarginBottom + ((MarginLayoutHelper) layoutHelper).mPaddingBottom;
}
if (top >= mOffset + mAdjuster.top) {
mDoNormalHandle = true;
}
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos > mPos) {
bottom = orientationHelper.getDecoratedStart(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(pos);
if (layoutHelper instanceof MarginLayoutHelper) {
bottom = bottom - ((MarginLayoutHelper) layoutHelper).mMarginTop - ((MarginLayoutHelper) layoutHelper).mPaddingTop;
}
if (bottom >= mOffset + mAdjuster.bottom) {
mDoNormalHandle = true;
}
break;
}
}
}
}
}
if (mDoNormalHandle || state.isPreLayout()) {
if (!state.isPreLayout()) {
// TODO: sticky only support one item now
}
if (mFixView != null) {
helper.removeChildView(mFixView);
} else {
// mDoNormalHandle == true && mFixView == null
return;
}
}
// Not in normal flow
if (!mDoNormalHandle && mFixView != null) {
// if it's not shown on screen
if (mFixView.getParent() == null) {
helper.addFixedView(mFixView);
} else {
if ((mStickyStart && endPosition >= mPos) || (!mStickyStart && startPosition <= mPos)) {
helper.showView(mFixView);
helper.addFixedView(mFixView);
} else {
helper.removeChildView(mFixView);
helper.recycleView(mFixView);
mFixView = null;
}
}
} else {
// 1. normal flow to abnormal flow; 2. abnormal flow to normal flow
// (mDoNormalHandle && mFixView != null) || (!mDoNormalHandle && mFixView == null)
View eView = mFixView;
if (eView == null)
// !mDoNormalHandle && mFixView == null, find existing view
eView = helper.findViewByPosition(mPos);
boolean normalHandle = false;
boolean layoutInVertical = helper.getOrientation() == VERTICAL;
final int startAdjust = layoutInVertical ? mAdjuster.top : mAdjuster.left;
final int endAdjust = layoutInVertical ? mAdjuster.bottom : mAdjuster.right;
if ((mStickyStart && endPosition >= mPos) || (!mStickyStart && startPosition <= mPos)) {
if (eView == null) {
// TODO? why do condition here?
if (mOffset + (mStickyStart ? startAdjust : endAdjust) > 0)
normalHandle = true;
mFixView = recycler.getViewForPosition(mPos);
doMeasure(mFixView, helper);
} else if (mStickyStart && orientationHelper.getDecoratedStart(eView) >= orientationHelper.getStartAfterPadding() + mOffset + startAdjust) {
// normal
normalHandle = true;
mFixView = eView;
} else if (!mStickyStart && orientationHelper.getDecoratedEnd(eView) <= orientationHelper.getEndAfterPadding() - mOffset - endAdjust) {
// normal
normalHandle = true;
mFixView = eView;
} else {
// abnormal
// TODO: reuse views
// mFixView = recycler.getViewForPosition(mPos);
mFixView = eView;
}
}
if (mFixView != null) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) mFixView.getLayoutParams();
if (params.isItemRemoved()) {
// item is removed
return;
}
// when do measure in after layout no need to consider scrolled
// doMeasure(mFixView, helper);
// do layout
int consumed = orientationHelper.getDecoratedMeasurement(mFixView);
int left = 0, top = 0, right = 0, bottom = 0;
int index = -1;
if (layoutInVertical) {
// not support RTL now
if (helper.isDoLayoutRTL()) {
right = helper.getContentWidth() - helper.getPaddingRight();
left = right - orientationHelper.getDecoratedMeasurementInOther(mFixView);
} else {
left = helper.getPaddingLeft();
right = left + orientationHelper.getDecoratedMeasurementInOther(mFixView);
}
if (normalHandle) {
View refer = null;
if (mStickyStart) {
for (int i = helper.getChildCount() - 1; i >= 0; i--) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos < mPos) {
// TODO: when view size is larger than totalSpace!
top = orientationHelper.getDecoratedEnd(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(pos);
if (layoutHelper instanceof MarginLayoutHelper) {
top = top + ((MarginLayoutHelper) layoutHelper).mMarginBottom + ((MarginLayoutHelper) layoutHelper).mPaddingBottom;
}
bottom = top + consumed;
index = i + 1;
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos > mPos) {
bottom = orientationHelper.getDecoratedStart(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(pos);
if (layoutHelper instanceof MarginLayoutHelper) {
bottom = bottom - ((MarginLayoutHelper) layoutHelper).mMarginTop - ((MarginLayoutHelper) layoutHelper).mPaddingTop;
}
top = bottom - consumed;
index = i;
break;
}
}
}
if (refer == null || index < 0) {
// can not find normal view for insert
normalHandle = false;
}
if (helper.getReverseLayout() || !mStickyStart) {
if (bottom > orientationHelper.getEndAfterPadding() - mOffset - endAdjust) {
normalHandle = false;
}
} else {
if (top < orientationHelper.getStartAfterPadding() + mOffset + startAdjust) {
normalHandle = false;
}
}
}
if (!normalHandle) {
if (helper.getReverseLayout() || !mStickyStart) {
bottom = orientationHelper.getEndAfterPadding() - mOffset - endAdjust;
top = bottom - consumed;
} else {
top = orientationHelper.getStartAfterPadding() + mOffset + startAdjust;
bottom = top + consumed;
}
}
} else {
top = helper.getPaddingTop();
bottom = top + orientationHelper.getDecoratedMeasurementInOther(mFixView);
if (normalHandle) {
View refer = null;
if (mStickyStart) {
for (int i = helper.getChildCount() - 1; i >= 0; i--) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos < mPos) {
// TODO: when view size is larger than totalSpace!
left = orientationHelper.getDecoratedEnd(refer);
right = left + consumed;
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int pos = helper.getPosition(refer);
if (pos > mPos) {
right = orientationHelper.getDecoratedStart(refer);
left = right - consumed;
break;
}
}
}
} else if (helper.getReverseLayout() || !mStickyStart) {
right = orientationHelper.getEndAfterPadding() - mOffset - endAdjust;
left = right - consumed;
} else {
left = orientationHelper.getStartAfterPadding() + mOffset + startAdjust;
right = left + consumed;
}
}
layoutChild(mFixView, left, top, right, bottom, helper);
if (normalHandle) {
// offset
if (index >= 0) {
helper.addChildView(mFixView, index);
mFixView = null;
}
} else
helper.addFixedView(mFixView);
}
}
}
Aggregations