Search in sources :

Example 26 with Recycler

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

Example 27 with Recycler

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

Example 28 with Recycler

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

Example 29 with Recycler

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

Example 30 with Recycler

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);
        }
    }
}
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)

Aggregations

RecyclerView (android.support.v7.widget.RecyclerView)106 View (android.view.View)100 TextView (android.widget.TextView)19 LinearLayoutManager (android.support.v7.widget.LinearLayoutManager)15 ImageView (android.widget.ImageView)13 OrientationHelper (android.support.v7.widget.OrientationHelper)12 GridLayoutManager (android.support.v7.widget.GridLayoutManager)10 ViewHolder (android.support.v7.widget.RecyclerView.ViewHolder)10 Point (android.graphics.Point)7 VirtualLayoutManager (com.alibaba.android.vlayout.VirtualLayoutManager)7 SuppressLint (android.annotation.SuppressLint)6 Context (android.content.Context)6 Bundle (android.os.Bundle)6 ActivityManager (android.app.ActivityManager)5 AccessibilityNodeInfoCompat (android.support.v4.view.accessibility.AccessibilityNodeInfoCompat)5 SpanSizeLookup (android.support.v7.widget.GridLayoutManager.SpanSizeLookup)5 LayoutParams (android.support.v7.widget.RecyclerView.LayoutParams)5 Recycler (android.support.v7.widget.RecyclerView.Recycler)5 RecyclerListener (android.support.v7.widget.RecyclerView.RecyclerListener)5 ViewGroup (android.view.ViewGroup)5