use of android.support.v7.widget.OrientationHelper 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);
}
}
}
use of android.support.v7.widget.OrientationHelper in project Signal-Android by WhisperSystems.
the class RecyclerViewPositionHelper method findOneVisibleChild.
View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) {
OrientationHelper helper;
if (layoutManager.canScrollVertically()) {
helper = OrientationHelper.createVerticalHelper(layoutManager);
} else {
helper = OrientationHelper.createHorizontalHelper(layoutManager);
}
final int start = helper.getStartAfterPadding();
final int end = helper.getEndAfterPadding();
final int next = toIndex > fromIndex ? 1 : -1;
View partiallyVisible = null;
for (int i = fromIndex; i != toIndex; i += next) {
final View child = layoutManager.getChildAt(i);
final int childStart = helper.getDecoratedStart(child);
final int childEnd = helper.getDecoratedEnd(child);
if (childStart < end && childEnd > start) {
if (completelyVisible) {
if (childStart >= start && childEnd <= end) {
return child;
} else if (acceptPartiallyVisible && partiallyVisible == null) {
partiallyVisible = child;
}
} else {
return child;
}
}
}
return partiallyVisible;
}
use of android.support.v7.widget.OrientationHelper in project RecyclerViewSnap by rubensousa.
the class GravityDelegate method findEndView.
@Nullable
private View findEndView(RecyclerView.LayoutManager layoutManager, @NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition() : linearLayoutManager.findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child) / helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child)) / helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList;
if (!reverseLayout) {
startOfList = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition() == 0;
} else {
startOfList = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1;
}
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset) : layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
use of android.support.v7.widget.OrientationHelper in project UltimateRecyclerView by cymcsg.
the class RecyclerViewPositionHelper method findOneVisibleChild.
private View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) {
OrientationHelper helper;
if (layoutManager.canScrollVertically()) {
helper = OrientationHelper.createVerticalHelper(layoutManager);
} else {
helper = OrientationHelper.createHorizontalHelper(layoutManager);
}
final int start = helper.getStartAfterPadding();
final int end = helper.getEndAfterPadding();
final int next = toIndex > fromIndex ? 1 : -1;
View partiallyVisible = null;
for (int i = fromIndex; i != toIndex; i += next) {
final View child = layoutManager.getChildAt(i);
final int childStart = helper.getDecoratedStart(child);
final int childEnd = helper.getDecoratedEnd(child);
if (childStart < end && childEnd > start) {
if (completelyVisible) {
if (childStart >= start && childEnd <= end) {
return child;
} else if (acceptPartiallyVisible && partiallyVisible == null) {
partiallyVisible = child;
}
} else {
return child;
}
}
}
return partiallyVisible;
}
use of android.support.v7.widget.OrientationHelper in project RecyclerViewSnap by rubensousa.
the class GravitySnapHelper method findStartView.
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the recyclerview's layout manager
* @param helper orientation helper to calculate view sizes
* @return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// In a RTL configuration, we need to check the start point and in LTR the end point
if (mIsRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child)) / helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child) / helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (mSnapLastItemEnabled && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + 1);
}
}
return null;
}
Aggregations