Search in sources :

Example 11 with OrientationHelper

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);
        }
    }
}
Also used : OrientationHelper(android.support.v7.widget.OrientationHelper) LayoutHelper(com.alibaba.android.vlayout.LayoutHelper) RecyclerView(android.support.v7.widget.RecyclerView) RecyclerView(android.support.v7.widget.RecyclerView) View(android.view.View)

Example 12 with OrientationHelper

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;
}
Also used : OrientationHelper(android.support.v7.widget.OrientationHelper) RecyclerView(android.support.v7.widget.RecyclerView) View(android.view.View)

Example 13 with OrientationHelper

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;
}
Also used : GridLayoutManager(android.support.v7.widget.GridLayoutManager) LinearLayoutManager(android.support.v7.widget.LinearLayoutManager) RecyclerView(android.support.v7.widget.RecyclerView) View(android.view.View) Nullable(android.support.annotation.Nullable)

Example 14 with OrientationHelper

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;
}
Also used : OrientationHelper(android.support.v7.widget.OrientationHelper) RecyclerView(android.support.v7.widget.RecyclerView) View(android.view.View)

Example 15 with OrientationHelper

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;
}
Also used : LinearLayoutManager(android.support.v7.widget.LinearLayoutManager) RecyclerView(android.support.v7.widget.RecyclerView) View(android.view.View)

Aggregations

OrientationHelper (android.support.v7.widget.OrientationHelper)21 RecyclerView (android.support.v7.widget.RecyclerView)21 View (android.view.View)21 VirtualLayoutManager (com.alibaba.android.vlayout.VirtualLayoutManager)10 LinearLayoutManager (android.support.v7.widget.LinearLayoutManager)4 LayoutParams (android.support.v7.widget.RecyclerView.LayoutParams)4 Nullable (android.support.annotation.Nullable)2 GridLayoutManager (android.support.v7.widget.GridLayoutManager)2 ViewGroup (android.view.ViewGroup)2 LayoutParams (android.view.ViewGroup.LayoutParams)1 TextView (android.widget.TextView)1 LayoutHelper (com.alibaba.android.vlayout.LayoutHelper)1 LayoutParams (com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams)1