use of com.alibaba.android.vlayout.LayoutHelper in project Tangram-Android by alibaba.
the class GroupBasicAdapter method transformCards.
/**
* Transform cards to layoutHelpers with correct range and add cells in cards into data
*
* @param cards cards will be transformed
* @param data list of items that items will be added to
* @return helpers transformed from cards
*/
@NonNull
protected List<LayoutHelper> transformCards(@Nullable List<L> cards, @NonNull final List<C> data, @NonNull List<Pair<Range<Integer>, L>> rangeCards) {
if (cards == null || cards.size() == 0) {
return new LinkedList<>();
}
int lastPos = data.size();
List<LayoutHelper> helpers = new ArrayList<>(cards.size());
for (int i = 0, size = cards.size(); i < size; i++) {
L card = cards.get(i);
if (card == null)
continue;
final String ctype = getCardStringType(card);
List<C> items = getItems(card);
if (items == null) {
// skip card null
continue;
}
data.addAll(items);
// calculate offset to set ranges
int offset = lastPos;
lastPos += items.size();
// include [x, x) for empty range, upper are not included in range
rangeCards.add(Pair.create(Range.create(offset, lastPos), card));
// get layoutHelper for this card
LayoutBinder<L> binder = mCardBinderResolver.create(ctype);
LayoutHelper helper = binder.getHelper(ctype, card);
if (helper != null) {
helper.setItemCount(items.size());
helpers.add(helper);
}
}
return helpers;
}
use of com.alibaba.android.vlayout.LayoutHelper in project vlayout by alibaba.
the class StickyLayoutHelper method fixLayoutStateFromAbnormal2Normal.
private void fixLayoutStateFromAbnormal2Normal(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, LayoutManagerHelper helper) {
// fix status, from abnormal to normal
if (VirtualLayoutManager.sDebuggable) {
Log.i(TAG, "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 anchorPos = helper.getPosition(refer);
if (anchorPos < mPos) {
// TODO: when view size is larger than totalSpace!
top = orientationHelper.getDecoratedEnd(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
top = top + ((RangeGridLayoutHelper) layoutHelper).getBorderEndSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
top = top + ((MarginLayoutHelper) layoutHelper).getMarginBottom() + ((MarginLayoutHelper) layoutHelper).getPaddingBottom();
}
if (top >= mOffset + mAdjuster.top) {
mDoNormalHandle = true;
}
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int anchorPos = helper.getPosition(refer);
if (anchorPos > mPos) {
bottom = orientationHelper.getDecoratedStart(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
bottom = bottom - ((RangeGridLayoutHelper) layoutHelper).getBorderStartSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
bottom = bottom - ((MarginLayoutHelper) layoutHelper).getMarginTop() - ((MarginLayoutHelper) layoutHelper).getPaddingTop();
}
if (bottom >= mOffset + mAdjuster.bottom) {
mDoNormalHandle = true;
}
break;
}
}
}
}
}
use of com.alibaba.android.vlayout.LayoutHelper in project vlayout by alibaba.
the class StickyLayoutHelper method fixLayoutStateInCase2.
private void fixLayoutStateInCase2(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, LayoutManagerHelper helper) {
// 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;
int extraTopOffset = getExtraTopOffset(helper);
final int startAdjust = layoutInVertical ? mAdjuster.top + extraTopOffset : 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 anchorPos = helper.getPosition(refer);
if (anchorPos < mPos) {
// TODO: when view size is larger than totalSpace!
top = orientationHelper.getDecoratedEnd(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
top = top + ((RangeGridLayoutHelper) layoutHelper).getBorderEndSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
top = top + ((MarginLayoutHelper) layoutHelper).getMarginBottom() + ((MarginLayoutHelper) layoutHelper).getPaddingBottom();
}
bottom = top + consumed;
index = i + 1;
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int anchorPos = helper.getPosition(refer);
if (anchorPos > mPos) {
bottom = orientationHelper.getDecoratedStart(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
bottom = bottom - ((RangeGridLayoutHelper) layoutHelper).getBorderStartSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
bottom = bottom - ((MarginLayoutHelper) layoutHelper).getMarginTop() - ((MarginLayoutHelper) layoutHelper).getPaddingTop();
}
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 anchorPos = helper.getPosition(refer);
if (anchorPos < 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 anchorPos = helper.getPosition(refer);
if (anchorPos > 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;
}
}
layoutChildWithMargin(mFixView, left, top, right, bottom, helper);
if (normalHandle) {
// offset
if (index >= 0) {
if (mFixView.getParent() == null) {
helper.addChildView(mFixView, index);
}
mFixView = null;
}
} else {
helper.addFixedView(mFixView);
}
}
mDoNormalHandle = normalHandle;
}
use of com.alibaba.android.vlayout.LayoutHelper in project vlayout by alibaba.
the class StickyLayoutHelper method fixLayoutStateInCase1.
private void fixLayoutStateInCase1(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, LayoutManagerHelper helper) {
// 1. normal flow to abnormal flow; 2. abnormal flow to normal flow
if ((mStickyStart && endPosition >= mPos) || (!mStickyStart && startPosition <= mPos)) {
int consumed = orientationHelper.getDecoratedMeasurement(mFixView);
boolean layoutInVertical = helper.getOrientation() == VERTICAL;
int extraTopOffset = getExtraTopOffset(helper);
final int startAdjust = layoutInVertical ? mAdjuster.top + extraTopOffset : mAdjuster.left;
final int endAdjust = layoutInVertical ? mAdjuster.bottom : mAdjuster.right;
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);
}
View refer = null;
if (mStickyStart) {
for (int i = helper.getChildCount() - 1; i >= 0; i--) {
refer = helper.getChildAt(i);
int anchorPos = helper.getPosition(refer);
if (anchorPos < mPos) {
top = orientationHelper.getDecoratedEnd(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
top = top + ((RangeGridLayoutHelper) layoutHelper).getBorderEndSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
top = top + ((MarginLayoutHelper) layoutHelper).getMarginBottom() + ((MarginLayoutHelper) layoutHelper).getPaddingBottom();
}
bottom = top + consumed;
index = i;
mDoNormalHandle = true;
break;
}
}
} else {
for (int i = 0; i < helper.getChildCount(); i++) {
refer = helper.getChildAt(i);
int anchorPos = helper.getPosition(refer);
if (anchorPos > mPos) {
// TODO: when view size is larger than totalSpace!
bottom = orientationHelper.getDecoratedStart(refer);
LayoutHelper layoutHelper = helper.findLayoutHelperByPosition(anchorPos);
if (layoutHelper instanceof RangeGridLayoutHelper) {
bottom = bottom - ((RangeGridLayoutHelper) layoutHelper).getBorderStartSpace(helper);
} else if (layoutHelper instanceof MarginLayoutHelper) {
bottom = bottom - ((MarginLayoutHelper) layoutHelper).getMarginTop() - ((MarginLayoutHelper) layoutHelper).getPaddingTop();
}
top = bottom - consumed;
index = i + 1;
mDoNormalHandle = true;
break;
}
}
}
if (refer == null || index < 0) {
// can not find normal view for insert
mDoNormalHandle = false;
}
if (helper.getReverseLayout() || !mStickyStart) {
if (bottom > orientationHelper.getEndAfterPadding() - mOffset - endAdjust) {
mDoNormalHandle = false;
}
} else {
if (top < orientationHelper.getStartAfterPadding() + mOffset + startAdjust) {
mDoNormalHandle = false;
}
}
if (!mDoNormalHandle) {
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 (mDoNormalHandle) {
View refer = null;
if (mStickyStart) {
for (int i = helper.getChildCount() - 1; i >= 0; i--) {
refer = helper.getChildAt(i);
int anchorPos = helper.getPosition(refer);
if (anchorPos < 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 anchorPos = helper.getPosition(refer);
if (anchorPos > 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;
}
}
layoutChildWithMargin(mFixView, left, top, right, bottom, helper);
if (mDoNormalHandle) {
// offset
if (index >= 0) {
if (mFixView.getParent() == null) {
helper.addChildView(mFixView, index);
}
mFixView = null;
}
} else {
helper.showView(mFixView);
helper.addFixedView(mFixView);
}
} else {
helper.removeChildView(mFixView);
helper.recycleView(mFixView);
mFixView = null;
}
}
use of com.alibaba.android.vlayout.LayoutHelper in project vlayout by alibaba.
the class StaggeredGridLayoutHelper method checkForGaps.
/**
* check whether there are gaps that need to be fixed
*/
private void checkForGaps() {
if (mLayoutManager == null) {
return;
}
final VirtualLayoutManager layoutManager = mLayoutManager.get();
if (layoutManager == null || layoutManager.getChildCount() == 0) {
return;
}
final Range<Integer> range = getRange();
// align position, which should check gap for
final int minPos, maxPos, alignPos;
if (layoutManager.getReverseLayout()) {
minPos = layoutManager.findLastVisibleItemPosition();
maxPos = layoutManager.findFirstVisibleItemPosition();
alignPos = range.getUpper() - 1;
} else {
minPos = layoutManager.findFirstVisibleItemPosition();
maxPos = layoutManager.findLastCompletelyVisibleItemPosition();
alignPos = range.getLower();
}
final OrientationHelperEx orientationHelper = layoutManager.getMainOrientationHelper();
final int childCount = layoutManager.getChildCount();
int viewAnchor = Integer.MIN_VALUE;
int alignLine = Integer.MIN_VALUE;
// find view anchor and get align line, the views should be aligned to alignLine
if (layoutManager.getReverseLayout()) {
for (int i = childCount - 1; i >= 0; i--) {
View view = layoutManager.getChildAt(i);
int position = layoutManager.getPosition(view);
if (position == alignPos) {
viewAnchor = position;
if (i == childCount - 1) {
// if last child, alignLine is the end of child
alignLine = orientationHelper.getDecoratedEnd(view);
} else {
// if not, alignLine is the start of next child
View child = layoutManager.getChildAt(i + 1);
int aPos = layoutManager.getPosition(child);
if (aPos == position - 1) {
// if position is sequence, which means the next child is not hidden one
alignLine = orientationHelper.getDecoratedStart(child) - layoutManager.obtainExtraMargin(child, false) + layoutManager.obtainExtraMargin(view, true);
} else {
// if next child is hidden one, use end of current view
alignLine = orientationHelper.getDecoratedEnd(view);
}
}
break;
}
}
} else {
for (int i = 0; i < childCount; i++) {
View view = layoutManager.getChildAt(i);
int position = layoutManager.getPosition(view);
if (position == alignPos) {
viewAnchor = position;
if (i == 0) {
// TODO: there is problem
// if first child, alignLine is the start
alignLine = orientationHelper.getDecoratedStart(view);
} else {
// if not, alignLine is the end of previous child
View child = layoutManager.getChildAt(i - 1);
alignLine = orientationHelper.getDecoratedEnd(child) + layoutManager.obtainExtraMargin(child, true, false) - layoutManager.obtainExtraMargin(view, false, false);
int viewStart = orientationHelper.getDecoratedStart(view);
if (alignLine == viewStart) {
// actually not gap here skip;
viewAnchor = Integer.MIN_VALUE;
} else {
int nextPosition = layoutManager.getPosition(child);
if (nextPosition != alignPos - 1) {
// may has sticky layout, add extra space occur by stickyLayoutHelper
LayoutHelper layoutHelper = layoutManager.findLayoutHelperByPosition(alignPos - 1);
if (layoutHelper != null && layoutHelper instanceof StickyLayoutHelper) {
if (layoutHelper.getFixedView() != null) {
alignLine += layoutHelper.getFixedView().getMeasuredHeight();
}
}
} else {
LayoutHelper layoutHelper = layoutManager.findLayoutHelperByPosition(nextPosition);
layoutHelper.getRange();
}
}
}
break;
}
}
}
if (viewAnchor == Integer.MIN_VALUE) {
// if not find view anchor, break
return;
}
View gapView = hasGapsToFix(layoutManager, viewAnchor, alignLine);
if (gapView != null) {
if (mSpans != null) {
for (int i = 0, size = mSpans.length; i < size; i++) {
Span span = mSpans[i];
span.setLine(alignLine);
}
}
layoutManager.requestSimpleAnimationsInNextLayout();
layoutManager.requestLayout();
}
}
Aggregations