From b56d1038f06e8ba6ff75edd97ce57fb9cb80c9c3 Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 2 Jan 2018 16:17:18 +0800 Subject: [PATCH 01/80] fix the bug of display item with large margin top or margin bottom --- .../alibaba/android/vlayout/VirtualLayoutManager.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index e7e17073..5fb17e5c 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -1372,10 +1372,15 @@ private void measureChildWithDecorations(View child, int widthSpec, int heightSp private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec) { calculateItemDecorationsForChild(child, mDecorInsets); RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams(); - widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left, + + if (getOrientation() == VERTICAL) { + widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left, lp.rightMargin + mDecorInsets.right); - heightSpec = updateSpecWithExtra(heightSpec, lp.topMargin + mDecorInsets.top, - lp.bottomMargin + mDecorInsets.bottom); + } + if (getOrientation() == HORIZONTAL) { + heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top, + mDecorInsets.bottom); + } child.measure(widthSpec, heightSpec); } From ce215f37229a7afde9880f404ef004b6e8080e6c Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 5 Jan 2018 19:52:39 +0800 Subject: [PATCH 02/80] fix measure item's with and height in floatLayoutHelper, see https://github.com/alibaba/Tangram-Android/issues/81 --- .../alibaba/android/vlayout/layout/FloatLayoutHelper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java index cf9c06f4..8254faf8 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java @@ -275,8 +275,8 @@ private void doMeasureAndLayout(View view, LayoutManagerHelper helper) { helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), params.height, layoutInVertical); } - // do measurement - helper.measureChildWithMargins(view, widthSpec, heightSpec); + // do measurement, measure child without taking off margins, see https://github.com/alibaba/Tangram-Android/issues/81 + helper.measureChild(view, widthSpec, heightSpec); } else { int widthSpec; final int heightSpec = helper.getChildMeasureSpec( @@ -294,8 +294,8 @@ private void doMeasureAndLayout(View view, LayoutManagerHelper helper) { helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), params.width, !layoutInVertical); } - // do measurement - helper.measureChildWithMargins(view, widthSpec, heightSpec); + // do measurement, measure child without taking off margins, see https://github.com/alibaba/Tangram-Android/issues/81 + helper.measureChild(view, widthSpec, heightSpec); } From 20d5a1570255fbc0f7365b0efcf304aa83f78320 Mon Sep 17 00:00:00 2001 From: longerian Date: Sun, 7 Jan 2018 17:36:53 +0800 Subject: [PATCH 03/80] refractor header and footer layout calculation for OnePlusNLayoutHeper to fix page's shift when layouting with anchor --- gradle.properties | 4 +- .../layout/AbstractFullFillLayoutHelper.java | 66 ++- .../vlayout/layout/BaseLayoutHelper.java | 29 -- .../vlayout/layout/OnePlusNLayoutHelper.java | 458 ++++++++---------- 4 files changed, 267 insertions(+), 290 deletions(-) diff --git a/gradle.properties b/gradle.properties index 13afc4cc..2738489e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,9 +44,9 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.6 +VERSION_NAME=1.2.6.4 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=23 systemProp.targetSdkVersion=23 -systemProp.buildToolsVersion=23.0.2 \ No newline at end of file +systemProp.buildToolsVersion=23.0.2 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java index 1b00ad70..4a038147 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java @@ -24,7 +24,10 @@ package com.alibaba.android.vlayout.layout; +import android.graphics.Rect; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Recycler; +import android.support.v7.widget.RecyclerView.State; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -45,6 +48,12 @@ public abstract class AbstractFullFillLayoutHelper extends BaseLayoutHelper { private static final String TAG = "FullFillLayoutHelper"; + protected boolean hasHeader = false; + + protected boolean hasFooter = false; + + protected boolean mLayoutWithAnchor = false; + protected int getAllChildren(View[] toFill, RecyclerView.Recycler recycler, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) { @@ -130,10 +139,26 @@ protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) @Override public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) { if (anchorInfo.layoutFromEnd) { - anchorInfo.position = getRange().getUpper(); + if (!hasFooter) { + anchorInfo.position = getRange().getUpper(); + } else { + //keep the previously calculated position + } } else { - anchorInfo.position = getRange().getLower(); + if (!hasHeader) { + anchorInfo.position = getRange().getLower(); + } else { + //keep the previously calculated position + } } + mLayoutWithAnchor = true; + } + + @Override + public void afterLayout(Recycler recycler, State state, int startPosition, int endPosition, int scrolled, + LayoutManagerHelper helper) { + super.afterLayout(recycler, state, startPosition, endPosition, scrolled, helper); + mLayoutWithAnchor = false; } @Override @@ -176,5 +201,42 @@ public boolean isRecyclable(int childPos, int startIndex, int endIndex, LayoutMa Log.w(TAG, "Child item not match"); return true; } + //NOTE may opt to recycle header or footer separately + } + + public void setHasHeader(boolean hasHeader) { + this.hasHeader = hasHeader; + } + + public void setHasFooter(boolean hasFooter) { + this.hasFooter = hasFooter; + } + + protected void calculateRect(int mainAxisSize, Rect areaRect, LayoutStateWrapper layoutState, LayoutManagerHelper helper) { + if (helper.getOrientation() == VirtualLayoutManager.VERTICAL) { + areaRect.left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + areaRect.right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight - mPaddingRight; + + // whether this layout pass is layout to start or to end + if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { + // fill start, from bottom to top + areaRect.bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : (hasFooter ? 0 : mMarginBottom + mPaddingBottom)); + areaRect.top = areaRect.bottom - mainAxisSize; + } else { + areaRect.top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : (hasHeader ? 0 : mMarginTop + mPaddingTop)); + areaRect.bottom = areaRect.top + mainAxisSize; + } + } else { + areaRect.top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + areaRect.bottom = helper.getContentHeight() - helper.getPaddingBottom() - mMarginBottom - mPaddingBottom; + + if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { + areaRect.right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 :(hasFooter ? 0 : mMarginRight + mPaddingRight)); + areaRect.left = areaRect.right - mainAxisSize; + } else { + areaRect.left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : (hasHeader ? 0 : mMarginLeft + mPaddingLeft)); + areaRect.right = areaRect.left + mainAxisSize; + } + } } } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index 4bb45106..f66e8f4e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -534,35 +534,6 @@ protected void handleStateOnResult(LayoutChunkResult result, View... views) { } } - - protected void calculateRect(int mainAxisSize, Rect areaRect, LayoutStateWrapper layoutState, LayoutManagerHelper helper) { - if (helper.getOrientation() == VirtualLayoutManager.VERTICAL) { - areaRect.left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; - areaRect.right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight - mPaddingRight; - - // whether this layout pass is layout to start or to end - if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - // fill start, from bottom to top - areaRect.bottom = layoutState.getOffset() - mMarginBottom - mPaddingBottom; - areaRect.top = areaRect.bottom - mainAxisSize; - } else { - areaRect.top = layoutState.getOffset() + mMarginTop + mPaddingTop; - areaRect.bottom = areaRect.top + mainAxisSize; - } - } else { - areaRect.top = helper.getPaddingTop() + mMarginTop + mPaddingTop; - areaRect.bottom = helper.getContentHeight() - helper.getPaddingBottom() - mMarginBottom - mPaddingBottom; - - if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - areaRect.right = layoutState.getOffset() - mMarginRight - mPaddingRight; - areaRect.left = areaRect.right - mainAxisSize; - } else { - areaRect.left = layoutState.getOffset() + mMarginLeft + mPaddingLeft; - areaRect.right = areaRect.left + mainAxisSize; - } - } - } - protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVertical, boolean isLayoutEnd, boolean isOverLapMargin) { int startSpace = 0; LayoutHelper lastLayoutHelper = null; diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index d250c8ae..f7e19887 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -24,19 +24,21 @@ package com.alibaba.android.vlayout.layout; -import android.graphics.Rect; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; +import java.util.Arrays; import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; +import com.alibaba.android.vlayout.VirtualLayoutManager.AnchorInfoWrapper; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; -import java.util.Arrays; +import android.graphics.Rect; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.State; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static com.alibaba.android.vlayout.VirtualLayoutManager.VERTICAL; @@ -110,20 +112,10 @@ public class OnePlusNLayoutHelper extends AbstractFullFillLayoutHelper { private View[] mChildrenViews; - private View mHeader; - - private View mFooter; - - private View[] mContentViews; - private float[] mColWeights = new float[0]; private float mRowWeight = Float.NaN; - private boolean hasHeader = false; - - private boolean hasFooter = false; - public OnePlusNLayoutHelper() { setItemCount(0); } @@ -156,13 +148,7 @@ public void onRangeChange(int start, int end) { } } - public void setHasHeader(boolean hasHeader) { - this.hasHeader = hasHeader; - } - public void setHasFooter(boolean hasFooter) { - this.hasFooter = hasFooter; - } public void setColWeights(float[] weights) { if (weights != null) { @@ -172,7 +158,6 @@ public void setColWeights(float[] weights) { } } - public void setRowWeight(float weight) { this.mRowWeight = weight; } @@ -184,79 +169,101 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (isOutOfRange(layoutState.getCurrentPosition())) { return; } - - final int originCurPos = layoutState.getCurrentPosition(); - - if (mChildrenViews == null || mChildrenViews.length != getItemCount()) { - mChildrenViews = new View[getItemCount()]; - } - - int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); - if (count == 0) { - return; - } - int contentCount = count; - if (hasHeader) { - contentCount = contentCount - 1; - mHeader = mChildrenViews[0]; - mChildrenViews[0] = null; - } - if (hasFooter) { - contentCount = contentCount - 1; - mFooter = mChildrenViews[count - 1]; - mChildrenViews[count - 1] = null; - } - if (mContentViews == null || mContentViews.length != contentCount) { - mContentViews = new View[contentCount]; - } - int j = 0; - for (int i = 0; i < mChildrenViews.length; i++) { - if (mChildrenViews[i] == null) { - continue; - } - mContentViews[j] = mChildrenViews[i]; - j++; - } - - if (count != getItemCount()) { - Log.w(TAG, "The real number of children is not match with range of LayoutHelper"); - } - + final OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final boolean layoutInVertical = helper.getOrientation() == VERTICAL; - + final boolean layoutStart = layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START; final int parentWidth = helper.getContentWidth(); final int parentHeight = helper.getContentHeight(); final int parentHPadding = helper.getPaddingLeft() + helper.getPaddingRight() - + getHorizontalMargin() + getHorizontalPadding(); + + getHorizontalMargin() + getHorizontalPadding(); final int parentVPadding = helper.getPaddingTop() + helper.getPaddingBottom() - + getVerticalMargin() + getVerticalPadding(); - - int mainConsumed = 0; - int headerConsumed = handleHeader(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, - parentHPadding, parentVPadding); - int footerConsumed = handleFooter(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, - parentHPadding, parentVPadding); - if (contentCount == 1) { - mainConsumed = handleOne(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 2) { - mainConsumed = handleTwo(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 3) { - mainConsumed = handleThree(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 4) { - mainConsumed = handleFour(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 5) { - mainConsumed = handleFive(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); + + getVerticalMargin() + getVerticalPadding(); + + final int currentPosition = layoutState.getCurrentPosition(); + if (hasHeader && currentPosition == getRange().getLower()) { + View header = nextView(recycler, layoutState, helper, result); + int headerConsumed = handleHeader(header, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, + parentHPadding, parentVPadding); + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset(); + top = bottom - headerConsumed; + } else { + top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginTop + mPaddingTop); + bottom = top + headerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(header); + } else { + if (layoutStart) { + right = layoutState.getOffset(); + left = right - headerConsumed; + } else { + left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginLeft + mPaddingLeft); + right = left + headerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(header); + } + layoutChildWithMargin(header, left, top, right, bottom, helper); + result.mConsumed = headerConsumed; + handleStateOnResult(result, header); + } else if (hasFooter && currentPosition == getRange().getUpper()) { + View footer = nextView(recycler, layoutState, helper, result); + int footerConsumed = handleFooter(footer, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, + parentHPadding, parentVPadding); + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); + top = bottom - footerConsumed; + } else { + top = layoutState.getOffset(); + bottom = top + footerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(footer); + } else { + if (layoutStart) { + right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); + left = right - footerConsumed; + } else { + left = layoutState.getOffset(); + right = left + footerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(footer); + } + layoutChildWithMargin(footer, left, top, right, bottom, helper); + result.mConsumed = footerConsumed; + handleStateOnResult(result, footer); + } else { + int contentCount = getItemCount() - (hasHeader ? 1 : 0) - (hasFooter ? 1 : 0); + if (mChildrenViews == null || mChildrenViews.length != contentCount) { + mChildrenViews = new View[contentCount]; + } + int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); + if (count == 0) { + return; + } + int mainConsumed = 0; + if (contentCount == 1) { + mainConsumed = handleOne(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 2) { + mainConsumed = handleTwo(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 3) { + mainConsumed = handleThree(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 4) { + mainConsumed = handleFour(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 5) { + mainConsumed = handleFive(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } + result.mConsumed = mainConsumed; + Arrays.fill(mChildrenViews, null); } - - result.mConsumed = mainConsumed; - - Arrays.fill(mChildrenViews, null); - Arrays.fill(mContentViews, null); - //mHeader = null; - //mFooter = null; } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { if (mColWeights.length > index) { return mColWeights[index]; @@ -268,84 +275,82 @@ private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) @Override protected void onClear(LayoutManagerHelper helper) { super.onClear(helper); - mHeader = null; - mFooter = null; + } + + @Override + public void checkAnchorInfo(State state, AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) { + super.checkAnchorInfo(state, anchorInfo, helper); + mLayoutWithAnchor = true; } @Override public int computeAlignOffset(int offset, boolean isLayoutEnd, boolean useAnchor, LayoutManagerHelper helper) { - //Log.d("Longer", "range " + getRange() + " offset " + offset + " isLayoutEnd " + isLayoutEnd + " useAnchor " + useAnchor + " mHeader " + (mHeader != null ? mHeader.hashCode() : "null")); - OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - if (offset == 1 && isLayoutEnd) { - Log.w(TAG, "Should not happen after adjust anchor without header"); + //Log.d(TAG, + // "range " + getRange() + " offset " + offset + " isLayoutEnd " + isLayoutEnd + " useAnchor " + useAnchor + // + " helper " + this.hashCode()); + final boolean layoutInVertical = helper.getOrientation() == LinearLayoutManager.VERTICAL; + + if (useAnchor) { return 0; - } else if (useAnchor) { - Log.w(TAG, "Happens when header scroll out of window and layoutManager use first content view as anchor to layout"); - return -mMarginTop - mPaddingTop - (mHeader != null ? orientationHelper.getDecoratedMeasurement(mHeader) : 0); } - - if (helper.getOrientation() == VERTICAL) { - if (isLayoutEnd) { - return mMarginBottom + mPaddingBottom; - } else { - return -mMarginTop - mPaddingTop; + if (isLayoutEnd) { + if (offset == getItemCount() - 1) { + return layoutInVertical ? mMarginBottom + mPaddingBottom : mMarginRight + mPaddingRight; } } else { - if (isLayoutEnd) { - return mMarginRight + mPaddingRight; - } else { - return -mMarginLeft - mPaddingLeft; + if (offset == 0) { + return layoutInVertical ? -mMarginTop - mPaddingTop : -mMarginLeft - mPaddingLeft; } } + return 0; } - private int handleHeader(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, + private int handleHeader(View header, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - if (mHeader == null) { + if (header == null) { return 0; } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - mHeader.getLayoutParams()); + header.getLayoutParams()); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical); int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical); - helper.measureChildWithMargins(mHeader, widthSpec, heightSpec); - return orientationHelper.getDecoratedMeasurement(mHeader); + helper.measureChildWithMargins(header, widthSpec, heightSpec); + return orientationHelper.getDecoratedMeasurement(header); } - private int handleFooter(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, + private int handleFooter(View footer, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - if (mFooter == null) { + if (footer == null) { return 0; } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - mFooter.getLayoutParams()); + footer.getLayoutParams()); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical); int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical); - helper.measureChildWithMargins(mFooter, widthSpec, heightSpec); - return orientationHelper.getDecoratedMeasurement(mFooter); + helper.measureChildWithMargins(footer, widthSpec, heightSpec); + return orientationHelper.getDecoratedMeasurement(footer); } private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - View view = mContentViews[0]; + View view = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams) view.getLayoutParams()); @@ -369,34 +374,26 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, helper.measureChildWithMargins(view, widthSpec, heightSpec); - mainConsumed += orientationHelper.getDecoratedMeasurement(view) + (layoutInVertical ? - getVerticalMargin() + getVerticalPadding() - : getHorizontalMargin() + getHorizontalPadding()); + mainConsumed += orientationHelper.getDecoratedMeasurement(view); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); + calculateRect(mainConsumed, mAreaRect, layoutState, helper); - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top + headerConsumed, mAreaRect.right, mAreaRect.bottom - footerConsumed, + layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.bottom, helper); - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } - handleStateOnResult(result, mHeader, view, mFooter); + handleStateOnResult(result, null, view, null); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); return mainConsumed; } private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); - final View child2 = mContentViews[1]; + final View child2 = mChildrenViews[1]; final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); final float weight1 = getViewMainWeight(lp1, 0); @@ -430,29 +427,19 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, helper.getChildMeasureSpec(helper.getContentHeight(), lp2.height, true)); mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), - orientationHelper.getDecoratedMeasurement(child2)) + getVerticalMargin() - + getVerticalPadding(); + orientationHelper.getDecoratedMeasurement(child2)); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); - layoutChildWithMargin(child2, - right1, mAreaRect.top + headerConsumed, - right1 + orientationHelper.getDecoratedMeasurementInOther(child2), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, + right1 + orientationHelper.getDecoratedMeasurementInOther(child2), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { if (!Float.isNaN(mAspectRatio)) { @@ -480,10 +467,9 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, MeasureSpec.EXACTLY)); mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), - orientationHelper.getDecoratedMeasurement(child2)) + getHorizontalMargin() - + getHorizontalPadding(); + orientationHelper.getDecoratedMeasurement(child2)); - calculateRect(mainConsumed - getHorizontalPadding() - getHorizontalMargin(), mAreaRect, layoutState, helper); + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int bottom1 = mAreaRect.top + orientationHelper .getDecoratedMeasurementInOther(child1); @@ -493,23 +479,23 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, layoutChildWithMargin(child2, mAreaRect.left, bottom1, mAreaRect.right, bottom1 + orientationHelper.getDecoratedMeasurementInOther(child2), helper); + mainConsumed = mAreaRect.right - mAreaRect.left + (hasHeader ? 0 : mMarginLeft + mPaddingRight) + (hasFooter ? 0 : mMarginRight + mPaddingRight); } - handleStateOnResult(result, mHeader, child1, child2, mFooter); + handleStateOnResult(result, null, child1, child2, null); return mainConsumed; } private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[2] : mContentViews[1]; - final View child3 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[2]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[1]; + final View child3 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[2]; final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); @@ -570,59 +556,45 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + height3 + lp3.topMargin - + lp3.bottomMargin) - + getVerticalMargin() + getVerticalPadding(); + + lp3.bottomMargin); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, right1, - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, - right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + child2.getMeasuredHeight() + lp2.topMargin - + lp2.bottomMargin + headerConsumed, helper); - - layoutChildWithMargin(child3, - right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right1 + orientationHelper.getDecoratedMeasurementInOther(child3), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + child2.getMeasuredHeight() + lp2.topMargin + lp2.bottomMargin, helper); + + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right1 + orientationHelper.getDecoratedMeasurementInOther(child3), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, mFooter); + handleStateOnResult(result, null, child1, child2, child3, null); return mainConsumed; } private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - int mainConsumed = headerConsumed + footerConsumed; + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[3] : mContentViews[1]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[1]; final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); - final View child3 = mContentViews[2]; + final View child3 = mChildrenViews[2]; final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); - final View child4 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[3]; + final View child4 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[3]; final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); @@ -692,64 +664,51 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + Math .max(height3 + lp3.topMargin + lp3.bottomMargin, - height3 + lp4.topMargin + lp4.bottomMargin)) - + getVerticalMargin() + getVerticalPadding(); + height3 + lp4.topMargin + lp4.bottomMargin)); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2) + headerConsumed, - helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2), helper); int right3 = right1 + orientationHelper.getDecoratedMeasurementInOther(child3); - layoutChildWithMargin(child3, right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right3, mAreaRect.bottom - footerConsumed, helper); - - layoutChildWithMargin(child4, right3, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4) - footerConsumed, - right3 + orientationHelper.getDecoratedMeasurementInOther(child4), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right3, mAreaRect.bottom, helper); + + layoutChildWithMargin(child4, right3, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4), + right3 + orientationHelper.getDecoratedMeasurementInOther(child4), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, child4, mFooter); + handleStateOnResult(result, null, child1, child2, child3, child4, null); return mainConsumed; } private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[4] : mContentViews[1]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); - final View child3 = helper.getReverseLayout() ? mContentViews[3] : mContentViews[2]; + final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); - final View child4 = helper.getReverseLayout() ? mContentViews[2] : mContentViews[3]; + final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); - final View child5 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[4]; + final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); @@ -830,48 +789,33 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + Math .max(height3 + lp3.topMargin + lp3.bottomMargin, - height3 + lp4.topMargin + lp4.bottomMargin)) - + getVerticalMargin() + getVerticalPadding(); - - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); + height3 + lp4.topMargin + lp4.bottomMargin)); - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); - int right1 = mAreaRect.left + orientationHelper - .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + int right1 = mAreaRect.left + orientationHelper.getDecoratedMeasurementInOther(child1); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2) + headerConsumed, - helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2), helper); int right3 = right1 + orientationHelper.getDecoratedMeasurementInOther(child3); - layoutChildWithMargin(child3, right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right3, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right3, mAreaRect.bottom, helper); int right4 = right3 + orientationHelper.getDecoratedMeasurementInOther(child4); - layoutChildWithMargin(child4, right3, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4) - footerConsumed, - right3 + orientationHelper.getDecoratedMeasurementInOther(child4), - mAreaRect.bottom - footerConsumed, helper); - - layoutChildWithMargin(child5, right4, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child5) - footerConsumed, - right4 + orientationHelper.getDecoratedMeasurementInOther(child5), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child4, right3, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4), + right3 + orientationHelper.getDecoratedMeasurementInOther(child4), mAreaRect.bottom, helper); + + layoutChildWithMargin(child5, right4, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child5), + right4 + orientationHelper.getDecoratedMeasurementInOther(child5), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, child4, child5, mFooter); + handleStateOnResult(result, null, child1, child2, child3, child4, child5, null); return mainConsumed; } From f856a1064eaaab0ea86738a8bc8827d5d0540690 Mon Sep 17 00:00:00 2001 From: longerian Date: Sun, 7 Jan 2018 19:24:13 +0800 Subject: [PATCH 04/80] fix startSpace and endSpace error when layout from end to start --- .../android/vlayout/ExposeLinearLayoutManagerEx.java | 11 +++++++++++ .../android/vlayout/layout/BaseLayoutHelper.java | 11 +++-------- .../android/vlayout/layout/RangeGridLayoutHelper.java | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java index ec3d5f0a..59ca1ca5 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java @@ -1739,11 +1739,22 @@ public void assignFromView(View child) { if (mLayoutFromEnd) { mCoordinate = mOrientationHelper.getDecoratedEnd(child) + computeAlignOffset(child, mLayoutFromEnd, true) + mOrientationHelper.getTotalSpaceChange(); + if (DEBUG) { + Log.d(TAG, "1 mLayoutFromEnd " + mLayoutFromEnd + " mOrientationHelper.getDecoratedEnd(child) " + + mOrientationHelper.getDecoratedEnd(child) + " computeAlignOffset(child, mLayoutFromEnd, true) " + computeAlignOffset(child, mLayoutFromEnd, true)); + } } else { mCoordinate = mOrientationHelper.getDecoratedStart(child) + computeAlignOffset(child, mLayoutFromEnd, true); + if (DEBUG) { + Log.d(TAG, "2 mLayoutFromEnd " + mLayoutFromEnd + " mOrientationHelper.getDecoratedStart(child) " + + mOrientationHelper.getDecoratedStart(child) + " computeAlignOffset(child, mLayoutFromEnd, true) " + computeAlignOffset(child, mLayoutFromEnd, true)); + } } mPosition = getPosition(child); + if (DEBUG) { + Log.d(TAG, "position " + mPosition + " mCoordinate " + mCoordinate); + } } } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index f66e8f4e..b67040b0 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -549,16 +549,12 @@ protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVert return 0; if (!isOverLapMargin) { - startSpace = layoutInVertical - ? (isLayoutEnd ? mMarginTop + mPaddingTop : mMarginBottom + mPaddingBottom) - : (isLayoutEnd ? mMarginLeft + mPaddingLeft : mMarginRight + mPaddingRight); + startSpace = layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft; } else { int offset = 0; if (lastMarginLayoutHelper == null) { - offset = layoutInVertical - ? (isLayoutEnd ? mMarginTop + mPaddingTop : mMarginBottom + mPaddingBottom) - : (isLayoutEnd ? mMarginLeft + mPaddingLeft : mMarginRight + mPaddingRight); + offset = layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft; } else { offset = layoutInVertical ? (isLayoutEnd ? calGap(lastMarginLayoutHelper.mMarginBottom, mMarginTop) : calGap(lastMarginLayoutHelper.mMarginTop, mMarginBottom)) @@ -576,8 +572,7 @@ protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVert protected int computeEndSpace(LayoutManagerHelper helper, boolean layoutInVertical, boolean isLayoutEnd, boolean isOverLapMargin) { int endSpace = layoutInVertical - ? (isLayoutEnd ? mMarginBottom + mPaddingBottom : mMarginTop + mPaddingTop) - : (isLayoutEnd ? mMarginRight + mPaddingRight : mMarginLeft + mPaddingLeft); + ? mMarginBottom + mPaddingBottom : mMarginLeft + mPaddingLeft; //Log.e("huang", "computeEndSpace offset: " + endSpace + ", isLayoutEnd: " + isLayoutEnd + ", " + this); //Log.e("huang", "===================\n\n"); return endSpace; diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java index 12b210db..9869032f 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java @@ -977,7 +977,7 @@ public static int computeStartAlignOffset(GridRangeStyle rangeStyle, boolean lay for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { GridRangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); if (!childRangeStyle.isChildrenEmpty()){ - //FIXEME may compute the wrong start space here + //FIXME may compute the wrong start space here offset += computeStartAlignOffset(childRangeStyle, layoutInVertical); }else if (childRangeStyle.mRange.getLower().intValue() == startPosition) { offset += (layoutInVertical ? -childRangeStyle.mMarginTop - childRangeStyle.mPaddingTop From 9037ec0080f8cb5742c6ab284efd4036b5adc312 Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 2 Jan 2018 16:17:18 +0800 Subject: [PATCH 05/80] fix the bug of display item with large margin top or margin bottom --- .../alibaba/android/vlayout/VirtualLayoutManager.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index e7e17073..5fb17e5c 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -1372,10 +1372,15 @@ private void measureChildWithDecorations(View child, int widthSpec, int heightSp private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec) { calculateItemDecorationsForChild(child, mDecorInsets); RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams(); - widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left, + + if (getOrientation() == VERTICAL) { + widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left, lp.rightMargin + mDecorInsets.right); - heightSpec = updateSpecWithExtra(heightSpec, lp.topMargin + mDecorInsets.top, - lp.bottomMargin + mDecorInsets.bottom); + } + if (getOrientation() == HORIZONTAL) { + heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top, + mDecorInsets.bottom); + } child.measure(widthSpec, heightSpec); } From cc51a975162ec141689493672199f564ad6bd408 Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 5 Jan 2018 19:52:39 +0800 Subject: [PATCH 06/80] fix measure item's with and height in floatLayoutHelper, see https://github.com/alibaba/Tangram-Android/issues/81 --- .../alibaba/android/vlayout/layout/FloatLayoutHelper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java index cf9c06f4..8254faf8 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/FloatLayoutHelper.java @@ -275,8 +275,8 @@ private void doMeasureAndLayout(View view, LayoutManagerHelper helper) { helper.getContentHeight() - helper.getPaddingTop() - helper.getPaddingBottom(), params.height, layoutInVertical); } - // do measurement - helper.measureChildWithMargins(view, widthSpec, heightSpec); + // do measurement, measure child without taking off margins, see https://github.com/alibaba/Tangram-Android/issues/81 + helper.measureChild(view, widthSpec, heightSpec); } else { int widthSpec; final int heightSpec = helper.getChildMeasureSpec( @@ -294,8 +294,8 @@ private void doMeasureAndLayout(View view, LayoutManagerHelper helper) { helper.getContentWidth() - helper.getPaddingLeft() - helper.getPaddingRight(), params.width, !layoutInVertical); } - // do measurement - helper.measureChildWithMargins(view, widthSpec, heightSpec); + // do measurement, measure child without taking off margins, see https://github.com/alibaba/Tangram-Android/issues/81 + helper.measureChild(view, widthSpec, heightSpec); } From 1538395a25ec9a8e8c7c686b2def73f5a5861d57 Mon Sep 17 00:00:00 2001 From: longerian Date: Sun, 7 Jan 2018 17:36:53 +0800 Subject: [PATCH 07/80] refractor header and footer layout calculation for OnePlusNLayoutHeper to fix page's shift when layouting with anchor --- gradle.properties | 4 +- .../layout/AbstractFullFillLayoutHelper.java | 66 ++- .../vlayout/layout/BaseLayoutHelper.java | 29 -- .../vlayout/layout/OnePlusNLayoutHelper.java | 458 ++++++++---------- 4 files changed, 267 insertions(+), 290 deletions(-) diff --git a/gradle.properties b/gradle.properties index 13afc4cc..2738489e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,9 +44,9 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.6 +VERSION_NAME=1.2.6.4 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=23 systemProp.targetSdkVersion=23 -systemProp.buildToolsVersion=23.0.2 \ No newline at end of file +systemProp.buildToolsVersion=23.0.2 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java index 1b00ad70..4a038147 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java @@ -24,7 +24,10 @@ package com.alibaba.android.vlayout.layout; +import android.graphics.Rect; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Recycler; +import android.support.v7.widget.RecyclerView.State; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -45,6 +48,12 @@ public abstract class AbstractFullFillLayoutHelper extends BaseLayoutHelper { private static final String TAG = "FullFillLayoutHelper"; + protected boolean hasHeader = false; + + protected boolean hasFooter = false; + + protected boolean mLayoutWithAnchor = false; + protected int getAllChildren(View[] toFill, RecyclerView.Recycler recycler, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper) { @@ -130,10 +139,26 @@ protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) @Override public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) { if (anchorInfo.layoutFromEnd) { - anchorInfo.position = getRange().getUpper(); + if (!hasFooter) { + anchorInfo.position = getRange().getUpper(); + } else { + //keep the previously calculated position + } } else { - anchorInfo.position = getRange().getLower(); + if (!hasHeader) { + anchorInfo.position = getRange().getLower(); + } else { + //keep the previously calculated position + } } + mLayoutWithAnchor = true; + } + + @Override + public void afterLayout(Recycler recycler, State state, int startPosition, int endPosition, int scrolled, + LayoutManagerHelper helper) { + super.afterLayout(recycler, state, startPosition, endPosition, scrolled, helper); + mLayoutWithAnchor = false; } @Override @@ -176,5 +201,42 @@ public boolean isRecyclable(int childPos, int startIndex, int endIndex, LayoutMa Log.w(TAG, "Child item not match"); return true; } + //NOTE may opt to recycle header or footer separately + } + + public void setHasHeader(boolean hasHeader) { + this.hasHeader = hasHeader; + } + + public void setHasFooter(boolean hasFooter) { + this.hasFooter = hasFooter; + } + + protected void calculateRect(int mainAxisSize, Rect areaRect, LayoutStateWrapper layoutState, LayoutManagerHelper helper) { + if (helper.getOrientation() == VirtualLayoutManager.VERTICAL) { + areaRect.left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + areaRect.right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight - mPaddingRight; + + // whether this layout pass is layout to start or to end + if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { + // fill start, from bottom to top + areaRect.bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : (hasFooter ? 0 : mMarginBottom + mPaddingBottom)); + areaRect.top = areaRect.bottom - mainAxisSize; + } else { + areaRect.top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : (hasHeader ? 0 : mMarginTop + mPaddingTop)); + areaRect.bottom = areaRect.top + mainAxisSize; + } + } else { + areaRect.top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + areaRect.bottom = helper.getContentHeight() - helper.getPaddingBottom() - mMarginBottom - mPaddingBottom; + + if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { + areaRect.right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 :(hasFooter ? 0 : mMarginRight + mPaddingRight)); + areaRect.left = areaRect.right - mainAxisSize; + } else { + areaRect.left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : (hasHeader ? 0 : mMarginLeft + mPaddingLeft)); + areaRect.right = areaRect.left + mainAxisSize; + } + } } } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index 4bb45106..f66e8f4e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -534,35 +534,6 @@ protected void handleStateOnResult(LayoutChunkResult result, View... views) { } } - - protected void calculateRect(int mainAxisSize, Rect areaRect, LayoutStateWrapper layoutState, LayoutManagerHelper helper) { - if (helper.getOrientation() == VirtualLayoutManager.VERTICAL) { - areaRect.left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; - areaRect.right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight - mPaddingRight; - - // whether this layout pass is layout to start or to end - if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - // fill start, from bottom to top - areaRect.bottom = layoutState.getOffset() - mMarginBottom - mPaddingBottom; - areaRect.top = areaRect.bottom - mainAxisSize; - } else { - areaRect.top = layoutState.getOffset() + mMarginTop + mPaddingTop; - areaRect.bottom = areaRect.top + mainAxisSize; - } - } else { - areaRect.top = helper.getPaddingTop() + mMarginTop + mPaddingTop; - areaRect.bottom = helper.getContentHeight() - helper.getPaddingBottom() - mMarginBottom - mPaddingBottom; - - if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - areaRect.right = layoutState.getOffset() - mMarginRight - mPaddingRight; - areaRect.left = areaRect.right - mainAxisSize; - } else { - areaRect.left = layoutState.getOffset() + mMarginLeft + mPaddingLeft; - areaRect.right = areaRect.left + mainAxisSize; - } - } - } - protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVertical, boolean isLayoutEnd, boolean isOverLapMargin) { int startSpace = 0; LayoutHelper lastLayoutHelper = null; diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index d250c8ae..f7e19887 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -24,19 +24,21 @@ package com.alibaba.android.vlayout.layout; -import android.graphics.Rect; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; +import java.util.Arrays; import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; +import com.alibaba.android.vlayout.VirtualLayoutManager.AnchorInfoWrapper; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; -import java.util.Arrays; +import android.graphics.Rect; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.State; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static com.alibaba.android.vlayout.VirtualLayoutManager.VERTICAL; @@ -110,20 +112,10 @@ public class OnePlusNLayoutHelper extends AbstractFullFillLayoutHelper { private View[] mChildrenViews; - private View mHeader; - - private View mFooter; - - private View[] mContentViews; - private float[] mColWeights = new float[0]; private float mRowWeight = Float.NaN; - private boolean hasHeader = false; - - private boolean hasFooter = false; - public OnePlusNLayoutHelper() { setItemCount(0); } @@ -156,13 +148,7 @@ public void onRangeChange(int start, int end) { } } - public void setHasHeader(boolean hasHeader) { - this.hasHeader = hasHeader; - } - public void setHasFooter(boolean hasFooter) { - this.hasFooter = hasFooter; - } public void setColWeights(float[] weights) { if (weights != null) { @@ -172,7 +158,6 @@ public void setColWeights(float[] weights) { } } - public void setRowWeight(float weight) { this.mRowWeight = weight; } @@ -184,79 +169,101 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (isOutOfRange(layoutState.getCurrentPosition())) { return; } - - final int originCurPos = layoutState.getCurrentPosition(); - - if (mChildrenViews == null || mChildrenViews.length != getItemCount()) { - mChildrenViews = new View[getItemCount()]; - } - - int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); - if (count == 0) { - return; - } - int contentCount = count; - if (hasHeader) { - contentCount = contentCount - 1; - mHeader = mChildrenViews[0]; - mChildrenViews[0] = null; - } - if (hasFooter) { - contentCount = contentCount - 1; - mFooter = mChildrenViews[count - 1]; - mChildrenViews[count - 1] = null; - } - if (mContentViews == null || mContentViews.length != contentCount) { - mContentViews = new View[contentCount]; - } - int j = 0; - for (int i = 0; i < mChildrenViews.length; i++) { - if (mChildrenViews[i] == null) { - continue; - } - mContentViews[j] = mChildrenViews[i]; - j++; - } - - if (count != getItemCount()) { - Log.w(TAG, "The real number of children is not match with range of LayoutHelper"); - } - + final OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final boolean layoutInVertical = helper.getOrientation() == VERTICAL; - + final boolean layoutStart = layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START; final int parentWidth = helper.getContentWidth(); final int parentHeight = helper.getContentHeight(); final int parentHPadding = helper.getPaddingLeft() + helper.getPaddingRight() - + getHorizontalMargin() + getHorizontalPadding(); + + getHorizontalMargin() + getHorizontalPadding(); final int parentVPadding = helper.getPaddingTop() + helper.getPaddingBottom() - + getVerticalMargin() + getVerticalPadding(); - - int mainConsumed = 0; - int headerConsumed = handleHeader(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, - parentHPadding, parentVPadding); - int footerConsumed = handleFooter(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, - parentHPadding, parentVPadding); - if (contentCount == 1) { - mainConsumed = handleOne(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 2) { - mainConsumed = handleTwo(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 3) { - mainConsumed = handleThree(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 4) { - mainConsumed = handleFour(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); - } else if (contentCount == 5) { - mainConsumed = handleFive(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding, headerConsumed, footerConsumed); + + getVerticalMargin() + getVerticalPadding(); + + final int currentPosition = layoutState.getCurrentPosition(); + if (hasHeader && currentPosition == getRange().getLower()) { + View header = nextView(recycler, layoutState, helper, result); + int headerConsumed = handleHeader(header, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, + parentHPadding, parentVPadding); + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset(); + top = bottom - headerConsumed; + } else { + top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginTop + mPaddingTop); + bottom = top + headerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(header); + } else { + if (layoutStart) { + right = layoutState.getOffset(); + left = right - headerConsumed; + } else { + left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginLeft + mPaddingLeft); + right = left + headerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(header); + } + layoutChildWithMargin(header, left, top, right, bottom, helper); + result.mConsumed = headerConsumed; + handleStateOnResult(result, header); + } else if (hasFooter && currentPosition == getRange().getUpper()) { + View footer = nextView(recycler, layoutState, helper, result); + int footerConsumed = handleFooter(footer, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, + parentHPadding, parentVPadding); + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); + top = bottom - footerConsumed; + } else { + top = layoutState.getOffset(); + bottom = top + footerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(footer); + } else { + if (layoutStart) { + right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); + left = right - footerConsumed; + } else { + left = layoutState.getOffset(); + right = left + footerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(footer); + } + layoutChildWithMargin(footer, left, top, right, bottom, helper); + result.mConsumed = footerConsumed; + handleStateOnResult(result, footer); + } else { + int contentCount = getItemCount() - (hasHeader ? 1 : 0) - (hasFooter ? 1 : 0); + if (mChildrenViews == null || mChildrenViews.length != contentCount) { + mChildrenViews = new View[contentCount]; + } + int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); + if (count == 0) { + return; + } + int mainConsumed = 0; + if (contentCount == 1) { + mainConsumed = handleOne(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 2) { + mainConsumed = handleTwo(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 3) { + mainConsumed = handleThree(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 4) { + mainConsumed = handleFour(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } else if (contentCount == 5) { + mainConsumed = handleFive(layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); + } + result.mConsumed = mainConsumed; + Arrays.fill(mChildrenViews, null); } - - result.mConsumed = mainConsumed; - - Arrays.fill(mChildrenViews, null); - Arrays.fill(mContentViews, null); - //mHeader = null; - //mFooter = null; } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { if (mColWeights.length > index) { return mColWeights[index]; @@ -268,84 +275,82 @@ private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) @Override protected void onClear(LayoutManagerHelper helper) { super.onClear(helper); - mHeader = null; - mFooter = null; + } + + @Override + public void checkAnchorInfo(State state, AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) { + super.checkAnchorInfo(state, anchorInfo, helper); + mLayoutWithAnchor = true; } @Override public int computeAlignOffset(int offset, boolean isLayoutEnd, boolean useAnchor, LayoutManagerHelper helper) { - //Log.d("Longer", "range " + getRange() + " offset " + offset + " isLayoutEnd " + isLayoutEnd + " useAnchor " + useAnchor + " mHeader " + (mHeader != null ? mHeader.hashCode() : "null")); - OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - if (offset == 1 && isLayoutEnd) { - Log.w(TAG, "Should not happen after adjust anchor without header"); + //Log.d(TAG, + // "range " + getRange() + " offset " + offset + " isLayoutEnd " + isLayoutEnd + " useAnchor " + useAnchor + // + " helper " + this.hashCode()); + final boolean layoutInVertical = helper.getOrientation() == LinearLayoutManager.VERTICAL; + + if (useAnchor) { return 0; - } else if (useAnchor) { - Log.w(TAG, "Happens when header scroll out of window and layoutManager use first content view as anchor to layout"); - return -mMarginTop - mPaddingTop - (mHeader != null ? orientationHelper.getDecoratedMeasurement(mHeader) : 0); } - - if (helper.getOrientation() == VERTICAL) { - if (isLayoutEnd) { - return mMarginBottom + mPaddingBottom; - } else { - return -mMarginTop - mPaddingTop; + if (isLayoutEnd) { + if (offset == getItemCount() - 1) { + return layoutInVertical ? mMarginBottom + mPaddingBottom : mMarginRight + mPaddingRight; } } else { - if (isLayoutEnd) { - return mMarginRight + mPaddingRight; - } else { - return -mMarginLeft - mPaddingLeft; + if (offset == 0) { + return layoutInVertical ? -mMarginTop - mPaddingTop : -mMarginLeft - mPaddingLeft; } } + return 0; } - private int handleHeader(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, + private int handleHeader(View header, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - if (mHeader == null) { + if (header == null) { return 0; } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - mHeader.getLayoutParams()); + header.getLayoutParams()); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical); int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical); - helper.measureChildWithMargins(mHeader, widthSpec, heightSpec); - return orientationHelper.getDecoratedMeasurement(mHeader); + helper.measureChildWithMargins(header, widthSpec, heightSpec); + return orientationHelper.getDecoratedMeasurement(header); } - private int handleFooter(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, + private int handleFooter(View footer, LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - if (mFooter == null) { + if (footer == null) { return 0; } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - mFooter.getLayoutParams()); + footer.getLayoutParams()); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical); int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical); - helper.measureChildWithMargins(mFooter, widthSpec, heightSpec); - return orientationHelper.getDecoratedMeasurement(mFooter); + helper.measureChildWithMargins(footer, widthSpec, heightSpec); + return orientationHelper.getDecoratedMeasurement(footer); } private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - View view = mContentViews[0]; + View view = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams) view.getLayoutParams()); @@ -369,34 +374,26 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, helper.measureChildWithMargins(view, widthSpec, heightSpec); - mainConsumed += orientationHelper.getDecoratedMeasurement(view) + (layoutInVertical ? - getVerticalMargin() + getVerticalPadding() - : getHorizontalMargin() + getHorizontalPadding()); + mainConsumed += orientationHelper.getDecoratedMeasurement(view); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); + calculateRect(mainConsumed, mAreaRect, layoutState, helper); - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top + headerConsumed, mAreaRect.right, mAreaRect.bottom - footerConsumed, + layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.bottom, helper); - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } - handleStateOnResult(result, mHeader, view, mFooter); + handleStateOnResult(result, null, view, null); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); return mainConsumed; } private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); - final View child2 = mContentViews[1]; + final View child2 = mChildrenViews[1]; final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); final float weight1 = getViewMainWeight(lp1, 0); @@ -430,29 +427,19 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, helper.getChildMeasureSpec(helper.getContentHeight(), lp2.height, true)); mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), - orientationHelper.getDecoratedMeasurement(child2)) + getVerticalMargin() - + getVerticalPadding(); + orientationHelper.getDecoratedMeasurement(child2)); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); - layoutChildWithMargin(child2, - right1, mAreaRect.top + headerConsumed, - right1 + orientationHelper.getDecoratedMeasurementInOther(child2), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, + right1 + orientationHelper.getDecoratedMeasurementInOther(child2), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { if (!Float.isNaN(mAspectRatio)) { @@ -480,10 +467,9 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, MeasureSpec.EXACTLY)); mainConsumed += Math.max(orientationHelper.getDecoratedMeasurement(child1), - orientationHelper.getDecoratedMeasurement(child2)) + getHorizontalMargin() - + getHorizontalPadding(); + orientationHelper.getDecoratedMeasurement(child2)); - calculateRect(mainConsumed - getHorizontalPadding() - getHorizontalMargin(), mAreaRect, layoutState, helper); + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int bottom1 = mAreaRect.top + orientationHelper .getDecoratedMeasurementInOther(child1); @@ -493,23 +479,23 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, layoutChildWithMargin(child2, mAreaRect.left, bottom1, mAreaRect.right, bottom1 + orientationHelper.getDecoratedMeasurementInOther(child2), helper); + mainConsumed = mAreaRect.right - mAreaRect.left + (hasHeader ? 0 : mMarginLeft + mPaddingRight) + (hasFooter ? 0 : mMarginRight + mPaddingRight); } - handleStateOnResult(result, mHeader, child1, child2, mFooter); + handleStateOnResult(result, null, child1, child2, null); return mainConsumed; } private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[2] : mContentViews[1]; - final View child3 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[2]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[1]; + final View child3 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[2]; final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); @@ -570,59 +556,45 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + height3 + lp3.topMargin - + lp3.bottomMargin) - + getVerticalMargin() + getVerticalPadding(); + + lp3.bottomMargin); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, right1, - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, - right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + child2.getMeasuredHeight() + lp2.topMargin - + lp2.bottomMargin + headerConsumed, helper); - - layoutChildWithMargin(child3, - right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right1 + orientationHelper.getDecoratedMeasurementInOther(child3), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + child2.getMeasuredHeight() + lp2.topMargin + lp2.bottomMargin, helper); + + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right1 + orientationHelper.getDecoratedMeasurementInOther(child3), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, mFooter); + handleStateOnResult(result, null, child1, child2, child3, null); return mainConsumed; } private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { - int mainConsumed = headerConsumed + footerConsumed; + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[3] : mContentViews[1]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[1]; final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); - final View child3 = mContentViews[2]; + final View child3 = mChildrenViews[2]; final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); - final View child4 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[3]; + final View child4 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[3]; final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); @@ -692,64 +664,51 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + Math .max(height3 + lp3.topMargin + lp3.bottomMargin, - height3 + lp4.topMargin + lp4.bottomMargin)) - + getVerticalMargin() + getVerticalPadding(); + height3 + lp4.topMargin + lp4.bottomMargin)); - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); - - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); int right1 = mAreaRect.left + orientationHelper .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2) + headerConsumed, - helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2), helper); int right3 = right1 + orientationHelper.getDecoratedMeasurementInOther(child3); - layoutChildWithMargin(child3, right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right3, mAreaRect.bottom - footerConsumed, helper); - - layoutChildWithMargin(child4, right3, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4) - footerConsumed, - right3 + orientationHelper.getDecoratedMeasurementInOther(child4), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right3, mAreaRect.bottom, helper); + + layoutChildWithMargin(child4, right3, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4), + right3 + orientationHelper.getDecoratedMeasurementInOther(child4), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, child4, mFooter); + handleStateOnResult(result, null, child1, child2, child3, child4, null); return mainConsumed; } private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, - boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding, - int headerConsumed, int footerConsumed) { - int mainConsumed = headerConsumed + footerConsumed; + boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { + int mainConsumed = 0; OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final View child1 = mContentViews[0]; + final View child1 = mChildrenViews[0]; final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); - final View child2 = helper.getReverseLayout() ? mContentViews[4] : mContentViews[1]; + final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); - final View child3 = helper.getReverseLayout() ? mContentViews[3] : mContentViews[2]; + final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); - final View child4 = helper.getReverseLayout() ? mContentViews[2] : mContentViews[3]; + final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); - final View child5 = helper.getReverseLayout() ? mContentViews[1] : mContentViews[4]; + final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); @@ -830,48 +789,33 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed += Math.max(height1 + lp1.topMargin + lp1.bottomMargin, height2 + lp2.topMargin + lp2.bottomMargin + Math .max(height3 + lp3.topMargin + lp3.bottomMargin, - height3 + lp4.topMargin + lp4.bottomMargin)) - + getVerticalMargin() + getVerticalPadding(); - - calculateRect(mainConsumed - getVerticalMargin() - getVerticalPadding(), mAreaRect, layoutState, helper); + height3 + lp4.topMargin + lp4.bottomMargin)); - if (mHeader != null) { - layoutChildWithMargin(mHeader, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.top + headerConsumed, helper); - } - if (mFooter != null) { - layoutChildWithMargin(mFooter, mAreaRect.left, mAreaRect.bottom - footerConsumed, mAreaRect.right, mAreaRect.bottom, helper); - } + calculateRect(mainConsumed, mAreaRect, layoutState, helper); - int right1 = mAreaRect.left + orientationHelper - .getDecoratedMeasurementInOther(child1); - layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top + headerConsumed, - right1, mAreaRect.bottom - footerConsumed, helper); + int right1 = mAreaRect.left + orientationHelper.getDecoratedMeasurementInOther(child1); + layoutChildWithMargin(child1, mAreaRect.left, mAreaRect.top, right1, mAreaRect.bottom, helper); int right2 = right1 + orientationHelper.getDecoratedMeasurementInOther(child2); - layoutChildWithMargin(child2, right1, mAreaRect.top + headerConsumed, right2, - mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2) + headerConsumed, - helper); + layoutChildWithMargin(child2, right1, mAreaRect.top, right2, + mAreaRect.top + orientationHelper.getDecoratedMeasurement(child2), helper); int right3 = right1 + orientationHelper.getDecoratedMeasurementInOther(child3); - layoutChildWithMargin(child3, right1, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3) - footerConsumed, - right3, mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child3, right1, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child3), + right3, mAreaRect.bottom, helper); int right4 = right3 + orientationHelper.getDecoratedMeasurementInOther(child4); - layoutChildWithMargin(child4, right3, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4) - footerConsumed, - right3 + orientationHelper.getDecoratedMeasurementInOther(child4), - mAreaRect.bottom - footerConsumed, helper); - - layoutChildWithMargin(child5, right4, - mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child5) - footerConsumed, - right4 + orientationHelper.getDecoratedMeasurementInOther(child5), - mAreaRect.bottom - footerConsumed, helper); + layoutChildWithMargin(child4, right3, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child4), + right3 + orientationHelper.getDecoratedMeasurementInOther(child4), mAreaRect.bottom, helper); + + layoutChildWithMargin(child5, right4, mAreaRect.bottom - orientationHelper.getDecoratedMeasurement(child5), + right4 + orientationHelper.getDecoratedMeasurementInOther(child5), mAreaRect.bottom, helper); + mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); } else { // TODO: horizontal support } - handleStateOnResult(result, mHeader, child1, child2, child3, child4, child5, mFooter); + handleStateOnResult(result, null, child1, child2, child3, child4, child5, null); return mainConsumed; } From e68722d1dad20b79a038d20d3645bcd3bcbd02a9 Mon Sep 17 00:00:00 2001 From: longerian Date: Sun, 7 Jan 2018 19:24:13 +0800 Subject: [PATCH 08/80] fix startSpace and endSpace error when layout from end to start --- .../android/vlayout/ExposeLinearLayoutManagerEx.java | 11 +++++++++++ .../android/vlayout/layout/BaseLayoutHelper.java | 11 +++-------- .../android/vlayout/layout/RangeGridLayoutHelper.java | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java index ec3d5f0a..59ca1ca5 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java @@ -1739,11 +1739,22 @@ public void assignFromView(View child) { if (mLayoutFromEnd) { mCoordinate = mOrientationHelper.getDecoratedEnd(child) + computeAlignOffset(child, mLayoutFromEnd, true) + mOrientationHelper.getTotalSpaceChange(); + if (DEBUG) { + Log.d(TAG, "1 mLayoutFromEnd " + mLayoutFromEnd + " mOrientationHelper.getDecoratedEnd(child) " + + mOrientationHelper.getDecoratedEnd(child) + " computeAlignOffset(child, mLayoutFromEnd, true) " + computeAlignOffset(child, mLayoutFromEnd, true)); + } } else { mCoordinate = mOrientationHelper.getDecoratedStart(child) + computeAlignOffset(child, mLayoutFromEnd, true); + if (DEBUG) { + Log.d(TAG, "2 mLayoutFromEnd " + mLayoutFromEnd + " mOrientationHelper.getDecoratedStart(child) " + + mOrientationHelper.getDecoratedStart(child) + " computeAlignOffset(child, mLayoutFromEnd, true) " + computeAlignOffset(child, mLayoutFromEnd, true)); + } } mPosition = getPosition(child); + if (DEBUG) { + Log.d(TAG, "position " + mPosition + " mCoordinate " + mCoordinate); + } } } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index f66e8f4e..b67040b0 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -549,16 +549,12 @@ protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVert return 0; if (!isOverLapMargin) { - startSpace = layoutInVertical - ? (isLayoutEnd ? mMarginTop + mPaddingTop : mMarginBottom + mPaddingBottom) - : (isLayoutEnd ? mMarginLeft + mPaddingLeft : mMarginRight + mPaddingRight); + startSpace = layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft; } else { int offset = 0; if (lastMarginLayoutHelper == null) { - offset = layoutInVertical - ? (isLayoutEnd ? mMarginTop + mPaddingTop : mMarginBottom + mPaddingBottom) - : (isLayoutEnd ? mMarginLeft + mPaddingLeft : mMarginRight + mPaddingRight); + offset = layoutInVertical ? mMarginTop + mPaddingTop : mMarginLeft + mPaddingLeft; } else { offset = layoutInVertical ? (isLayoutEnd ? calGap(lastMarginLayoutHelper.mMarginBottom, mMarginTop) : calGap(lastMarginLayoutHelper.mMarginTop, mMarginBottom)) @@ -576,8 +572,7 @@ protected int computeStartSpace(LayoutManagerHelper helper, boolean layoutInVert protected int computeEndSpace(LayoutManagerHelper helper, boolean layoutInVertical, boolean isLayoutEnd, boolean isOverLapMargin) { int endSpace = layoutInVertical - ? (isLayoutEnd ? mMarginBottom + mPaddingBottom : mMarginTop + mPaddingTop) - : (isLayoutEnd ? mMarginRight + mPaddingRight : mMarginLeft + mPaddingLeft); + ? mMarginBottom + mPaddingBottom : mMarginLeft + mPaddingLeft; //Log.e("huang", "computeEndSpace offset: " + endSpace + ", isLayoutEnd: " + isLayoutEnd + ", " + this); //Log.e("huang", "===================\n\n"); return endSpace; diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java index 12b210db..9869032f 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java @@ -977,7 +977,7 @@ public static int computeStartAlignOffset(GridRangeStyle rangeStyle, boolean lay for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { GridRangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); if (!childRangeStyle.isChildrenEmpty()){ - //FIXEME may compute the wrong start space here + //FIXME may compute the wrong start space here offset += computeStartAlignOffset(childRangeStyle, layoutInVertical); }else if (childRangeStyle.mRange.getLower().intValue() == startPosition) { offset += (layoutInVertical ? -childRangeStyle.mMarginTop - childRangeStyle.mPaddingTop From 64c04678d77156e454e864ead2427d11a5b55beb Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 9 Jan 2018 11:43:44 +0800 Subject: [PATCH 09/80] fix npe in prelayout, recycler header and footer separately --- .../layout/AbstractFullFillLayoutHelper.java | 11 ++- .../vlayout/layout/OnePlusNLayoutHelper.java | 88 ++++++++++--------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java index 4a038147..208aaf76 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/AbstractFullFillLayoutHelper.java @@ -196,12 +196,19 @@ protected LayoutParams generateLayoutParams(LayoutParams p) { public boolean isRecyclable(int childPos, int startIndex, int endIndex, LayoutManagerHelper helper, boolean fromStart) { Range range = getRange(); if (range.contains(childPos)) { - return Range.create(startIndex, endIndex).contains(range); + if (hasHeader && childPos == getRange().getLower()) { + return true; + } + if (hasFooter && childPos == getRange().getUpper()) { + return true; + } + Range childRange = Range.create(range.getLower() + (hasHeader ? 1 : 0), + range.getUpper() - (hasFooter ? 1 : 0)); + return Range.create(startIndex, endIndex).contains(childRange); } else { Log.w(TAG, "Child item not match"); return true; } - //NOTE may opt to recycle header or footer separately } public void setHasHeader(boolean hasHeader) { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index f7e19887..2baab623 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -36,6 +36,7 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.State; +import android.util.Log; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; @@ -180,62 +181,67 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state + getVerticalMargin() + getVerticalPadding(); final int currentPosition = layoutState.getCurrentPosition(); + Log.d("Longer", "currentPosition " + currentPosition); if (hasHeader && currentPosition == getRange().getLower()) { View header = nextView(recycler, layoutState, helper, result); int headerConsumed = handleHeader(header, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); - int left = 0, right = 0, top = 0, bottom = 0; - if (layoutInVertical) { - if (layoutStart) { - bottom = layoutState.getOffset(); - top = bottom - headerConsumed; - } else { - top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginTop + mPaddingTop); - bottom = top + headerConsumed; - } - left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; - right = left + orientationHelper.getDecoratedMeasurementInOther(header); - } else { - if (layoutStart) { - right = layoutState.getOffset(); - left = right - headerConsumed; + if (header != null) { + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset(); + top = bottom - headerConsumed; + } else { + top = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginTop + mPaddingTop); + bottom = top + headerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(header); } else { - left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginLeft + mPaddingLeft); - right = left + headerConsumed; + if (layoutStart) { + right = layoutState.getOffset(); + left = right - headerConsumed; + } else { + left = layoutState.getOffset() + (mLayoutWithAnchor ? 0 : mMarginLeft + mPaddingLeft); + right = left + headerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(header); } - top = helper.getPaddingTop() + mMarginTop + mPaddingTop; - bottom = top + orientationHelper.getDecoratedMeasurementInOther(header); + layoutChildWithMargin(header, left, top, right, bottom, helper); } - layoutChildWithMargin(header, left, top, right, bottom, helper); result.mConsumed = headerConsumed; handleStateOnResult(result, header); } else if (hasFooter && currentPosition == getRange().getUpper()) { View footer = nextView(recycler, layoutState, helper, result); int footerConsumed = handleFooter(footer, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, parentHPadding, parentVPadding); - int left = 0, right = 0, top = 0, bottom = 0; - if (layoutInVertical) { - if (layoutStart) { - bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); - top = bottom - footerConsumed; - } else { - top = layoutState.getOffset(); - bottom = top + footerConsumed; - } - left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; - right = left + orientationHelper.getDecoratedMeasurementInOther(footer); - } else { - if (layoutStart) { - right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); - left = right - footerConsumed; + if (footer != null) { + int left = 0, right = 0, top = 0, bottom = 0; + if (layoutInVertical) { + if (layoutStart) { + bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); + top = bottom - footerConsumed; + } else { + top = layoutState.getOffset(); + bottom = top + footerConsumed; + } + left = helper.getPaddingLeft() + mMarginLeft + mPaddingLeft; + right = left + orientationHelper.getDecoratedMeasurementInOther(footer); } else { - left = layoutState.getOffset(); - right = left + footerConsumed; + if (layoutStart) { + right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); + left = right - footerConsumed; + } else { + left = layoutState.getOffset(); + right = left + footerConsumed; + } + top = helper.getPaddingTop() + mMarginTop + mPaddingTop; + bottom = top + orientationHelper.getDecoratedMeasurementInOther(footer); } - top = helper.getPaddingTop() + mMarginTop + mPaddingTop; - bottom = top + orientationHelper.getDecoratedMeasurementInOther(footer); + layoutChildWithMargin(footer, left, top, right, bottom, helper); } - layoutChildWithMargin(footer, left, top, right, bottom, helper); result.mConsumed = footerConsumed; handleStateOnResult(result, footer); } else { @@ -244,7 +250,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state mChildrenViews = new View[contentCount]; } int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); - if (count == 0) { + if (count == 0 || count < mChildrenViews.length) { return; } int mainConsumed = 0; From d3b59647433aa703a33f10ccd2ae6e03eef12fab Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 9 Jan 2018 11:46:33 +0800 Subject: [PATCH 10/80] update if-condition --- .../alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index 2baab623..727884e4 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -250,7 +250,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state mChildrenViews = new View[contentCount]; } int count = getAllChildren(mChildrenViews, recycler, layoutState, result, helper); - if (count == 0 || count < mChildrenViews.length) { + if (count == 0 || count < contentCount) { return; } int mainConsumed = 0; From 6c505cabbcdecc6917dc15ec01799a00edc9e2e7 Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Tue, 9 Jan 2018 12:07:44 +0800 Subject: [PATCH 11/80] Update VLayoutFAQ.md --- docs/VLayoutFAQ.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/docs/VLayoutFAQ.md b/docs/VLayoutFAQ.md index fbbe4e1b..8781e6a0 100644 --- a/docs/VLayoutFAQ.md +++ b/docs/VLayoutFAQ.md @@ -121,3 +121,94 @@ layoutHelper 根据 item 元素的位置和大小确定整块背景的大小, ## 判断 `StickyLayoutHelper` 里的 item 是否到达顶部 通过 `virtualLayoutManager.findFirstVisibleItemPosition()`,如果大于 `StickyLayoutHelper` 里的 item 的位置,说明已经到顶部。[#277](https://github.com/alibaba/vlayout/issues/277) + +## 滚动到某个 item 位置,并带偏移一个距离 +有时候自带的 scrollToPosition 方法或者 smoothScrollToPosition 方法不满足需求,可以尝试自己用动画驱动做一个滚动,下面是一种参考实现,可以基于此调整动画参数; + +``` +public class RecyclerViewFlinger implements Runnable { + + private static final String TAG = "Flinger"; + + private static final float MILLISECONDS_PER_INCH = 25.0F; + + private RecyclerView mRecyclerView; + + private int targetPosition; + + private int offset; + + private int direction = 1; + + private ScrollFinishedListener mFinishedListener; + + private int lastTop; + + private int step; + + public RecyclerViewFlinger(RecyclerView recyclerView, int targetPosition, int offset, + ScrollFinishedListener finishedListener) { +        this.mRecyclerView = recyclerView; +        this.targetPosition = targetPosition; //targetPosition 目标item的位置 +        this.offset = offset;//offset 是目标 item 距离顶部的偏移量 +        this.mFinishedListener = finishedListener;//可以设置一个滚动回调 + if (mRecyclerView != null) { + int firstVisibleItemPosition = mRecyclerView.getFirstVisiblePosition(); + direction = firstVisibleItemPosition < targetPosition ? 1 : -1; + } +        this.step = mRecyclerView.getMeasuredHeight() / 2; //滚动步长,时间等都可以细调 + } + + @Override + public void run() { + if (mRecyclerView != null) { + int firstVisibleItemPosition = mRecyclerView.getFirstVisiblePosition(); + int lastVisibleItemPosition = mRecyclerView.getLastVisiblePosition(); + boolean inscreen = targetPosition >= firstVisibleItemPosition && targetPosition <= lastVisibleItemPosition; + if (inscreen) { + View targetView = mRecyclerView.getLayoutManager().findViewByPosition(targetPosition); + if (targetView != null) { + int top = targetView.getTop(); + int dy = top - offset; + mRecyclerView.smoothScrollBy(0, dy); + if (lastTop == top) { + if (mFinishedListener != null) { + mFinishedListener.onPostExecute(targetView); + } + } else { + lastTop = top; + postOnAnimation(); + } + } + } else { + mRecyclerView.smoothScrollBy(0, step * direction); + postOnAnimation(); + } + + } + } + + public void postOnAnimation() { + if (mRecyclerView == null) { + return; + } + ViewCompat.postOnAnimation(mRecyclerView, this); + } + + public void stop() { + mFinishedListener = null; + if (mRecyclerView == null) { + return; + } + mRecyclerView.removeCallbacks(this); + } + + public interface ScrollFinishedListener { + void onPostExecute(View view); + } + +} +``` + + + From d3ec94519443d0ea326d83a9ae685eb01278d2cb Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 9 Jan 2018 19:35:46 +0800 Subject: [PATCH 12/80] delete log --- .../android/vlayout/layout/OnePlusNLayoutHelper.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index 727884e4..fabfcd99 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -36,7 +36,6 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.State; -import android.util.Log; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; @@ -181,7 +180,6 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state + getVerticalMargin() + getVerticalPadding(); final int currentPosition = layoutState.getCurrentPosition(); - Log.d("Longer", "currentPosition " + currentPosition); if (hasHeader && currentPosition == getRange().getLower()) { View header = nextView(recycler, layoutState, helper, result); int headerConsumed = handleHeader(header, layoutState, result, helper, layoutInVertical, parentWidth, parentHeight, @@ -221,7 +219,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state int left = 0, right = 0, top = 0, bottom = 0; if (layoutInVertical) { if (layoutStart) { - bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); + bottom = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginBottom + mPaddingBottom); //TODO margin overlap top = bottom - footerConsumed; } else { top = layoutState.getOffset(); @@ -231,7 +229,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state right = left + orientationHelper.getDecoratedMeasurementInOther(footer); } else { if (layoutStart) { - right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); + right = layoutState.getOffset() - (mLayoutWithAnchor ? 0 : mMarginRight + mPaddingRight); //TODO margin overlap left = right - footerConsumed; } else { left = layoutState.getOffset(); From ce49bd1bde11f2b29eb3b08f0cdbc45dd99d6b74 Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 10 Jan 2018 11:03:15 +0800 Subject: [PATCH 13/80] fix page shifting when layout with anchor --- .../layout/StaggeredGridLayoutHelper.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 08cb76d3..3d5c69eb 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -89,6 +89,10 @@ public class StaggeredGridLayoutHelper extends BaseLayoutHelper { private List prelayoutViewList = new ArrayList<>(); + private boolean mLayoutWithAnchor; + + private int anchorPosition; + private WeakReference mLayoutManager = null; private final Runnable checkForGapsRunnable = new Runnable() { @@ -190,6 +194,7 @@ public void beforeLayout(RecyclerView.Recycler recycler, RecyclerView.State stat @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); + mLayoutWithAnchor = false; if (startPosition > getRange().getUpper() || endPosition < getRange().getLower()) { //do not in visible screen, skip return; @@ -239,6 +244,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state prelayoutViewList.clear(); while (layoutState.hasMore(state) && !mRemainingSpans.isEmpty() && !isOutOfRange(layoutState.getCurrentPosition())) { boolean isStartLine = false, isEndLine = false; + int currentPosition = layoutState.getCurrentPosition(); View view = layoutState.next(recycler); if (view == null) { @@ -260,7 +266,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } // handle margin for start/end line isStartLine = position - getRange().getLower() < mNumLanes; - isEndLine = getRange().getUpper() - position < mNumLanes; //fix the end line condiition + isEndLine = getRange().getUpper() - position < mNumLanes; //fix the end line condition, edit by longerian if (layoutState.isPreLayout()) { prelayoutViewList.add(view); @@ -291,15 +297,22 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (isStartLine) { start += computeStartSpace(helper, layoutInVertical, true, isOverLapMargin); - //Log.d(TAG", "startLine " + position + " " + start); } else { - start += (layoutInVertical ? mVGap : mHGap); - //Log.d(TAG", "normalStartLine " + position + " " + start); + if (mLayoutWithAnchor) { + if (Math.abs(currentPosition - anchorPosition) < mNumLanes) { + //do not add extra gaps here + } else { + start += (layoutInVertical ? mVGap : mHGap); + } + } else { + start += (layoutInVertical ? mVGap : mHGap); + } } end = start + orientationHelper.getDecoratedMeasurement(view); } else { if (isEndLine) { - end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? mMarginBottom + mPaddingRight : mMarginRight + mPaddingRight); + end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? + mMarginBottom + mPaddingRight : mMarginRight + mPaddingRight); //Log.d(TAG, "endLine " + position + " " + end); } else { end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? mVGap : mHGap); @@ -997,6 +1010,9 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho } } } + } else { + anchorPosition = anchorInfo.position; + mLayoutWithAnchor = true; } if (BuildConfig.DEBUG) { @@ -1173,6 +1189,7 @@ void cacheReferenceLineAndClear(boolean reverseLayout, int offset, OrientationHe } void clear() { + Log.d("Longer", "clear span"); mViews.clear(); invalidateCache(); mDeletedSize = 0; From 7184b5f78718d448a737c4791fcfbdfe33b628c4 Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 10 Jan 2018 14:21:40 +0800 Subject: [PATCH 14/80] Update README-ch.md --- README-ch.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README-ch.md b/README-ch.md index 6d54003d..7f5ac406 100644 --- a/README-ch.md +++ b/README-ch.md @@ -42,10 +42,10 @@ VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一 ## 使用 -版本请参考mvn repository上的最新版本(目前最新版本是1.2.6),最新的 aar 都会发布到 jcenter 和 MavenCentral 上,确保配置了这两个仓库源,然后引入aar依赖: +版本请参考 [release 说明](https://github.com/alibaba/vlayout/releases)里的最新版本,最新的 aar 都会发布到 jcenter 和 MavenCentral 上,确保配置了这两个仓库源,然后引入aar依赖: ``` gradle -compile ('com.alibaba.android:vlayout:1.2.6@aar') { +compile ('com.alibaba.android:vlayout:1.2.8@aar') { transitive = true } ``` @@ -56,7 +56,7 @@ pom.xml com.alibaba.android vlayout - 1.2.6 + 1.2.8 aar ``` From f10cff2d16c0dbeee798cfeeed392d1c13960f7b Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 10 Jan 2018 14:22:50 +0800 Subject: [PATCH 15/80] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9f6450eb..76b41b7f 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ By providing a custom LayoutManager to RecyclerView, VirtualLayout is able to la ### Import Library -Please find the latest version(1.2.6 so far) in maven repository. The newest version has been upload to jcenter and MavenCentral, make sure you have added at least one of these repositories. +Please find the latest version in [release notes](https://github.com/alibaba/vlayout/releases). The newest version has been upload to jcenter and MavenCentral, make sure you have added at least one of these repositories. As follow: For gradle: ``` gradle -compile ('com.alibaba.android:vlayout:1.2.6@aar') { +compile ('com.alibaba.android:vlayout:1.2.8@aar') { transitive = true } ``` @@ -57,7 +57,7 @@ pom.xml com.alibaba.android vlayout - 1.2.6 + 1.2.8 aar ``` From 22d76f32799efcdc08ad95c43dbf859b57d49e56 Mon Sep 17 00:00:00 2001 From: longerian Date: Sun, 14 Jan 2018 13:03:38 +0800 Subject: [PATCH 16/80] fix #223 --- .../android/vlayout/layout/LinearLayoutHelper.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/LinearLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/LinearLayoutHelper.java index 2e6b3a38..b21f47c2 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/LinearLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/LinearLayoutHelper.java @@ -27,9 +27,11 @@ import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; +import com.alibaba.android.vlayout.VirtualLayoutManager.AnchorInfoWrapper; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.State; import android.util.Log; import android.view.View; @@ -47,6 +49,8 @@ public class LinearLayoutHelper extends BaseLayoutHelper { private int mDividerHeight = 0; + private boolean mLayoutWithAnchor = false; + public LinearLayoutHelper() { this(0); } @@ -113,8 +117,9 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (!isStartLine) { if (!isOverLapMargin) { - gap = mDividerHeight; + gap = mLayoutWithAnchor ? 0 : mDividerHeight; } else { + //TODO check layout with anchor if (isLayoutEnd) { int marginTop = params.topMargin; View sibling = helper.findViewByPosition(currentPosition - 1); @@ -209,6 +214,13 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } handleStateOnResult(result, view); + mLayoutWithAnchor = false; + } + + @Override + public void checkAnchorInfo(State state, AnchorInfoWrapper anchorInfo, LayoutManagerHelper helper) { + super.checkAnchorInfo(state, anchorInfo, helper); + mLayoutWithAnchor = true; } @Override From 7e1b9b3c85ba480390a9c89eebf3bfe513fd4566 Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 17 Jan 2018 11:20:34 +0800 Subject: [PATCH 17/80] remove log --- .../android/vlayout/layout/StaggeredGridLayoutHelper.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 3d5c69eb..266c8355 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -41,7 +41,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.view.ViewCompat; -import android.support.v7.widget.OrientationHelper; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.LayoutParams; import android.util.Log; @@ -1189,7 +1188,6 @@ void cacheReferenceLineAndClear(boolean reverseLayout, int offset, OrientationHe } void clear() { - Log.d("Longer", "clear span"); mViews.clear(); invalidateCache(); mDeletedSize = 0; From 5d2d7ca14e8029cded7f91f35ff7e962c33e2d64 Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 17 Jan 2018 14:49:24 +0800 Subject: [PATCH 18/80] test maven sync --- jcenterDeploy.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jcenterDeploy.gradle b/jcenterDeploy.gradle index fcb5618a..33f55430 100644 --- a/jcenterDeploy.gradle +++ b/jcenterDeploy.gradle @@ -113,6 +113,13 @@ bintray { passphrase = project.hasProperty('bintrayGPG') ? project.getProperty('bintrayGPG') : "" //Optional. The passphrase for GPG signing' } + + mavenCentralSync { + sync = true + user = project.hasProperty('bintray.oss.user') ? project.getProperty('bintray.oss.user') : "" + password = project.hasProperty('bintray.oss.password') ? project.getProperty('bintray.oss.password') : "" + close = '1' + } } } } From 69e7e2878f64ab1870046efa8983d0192bccf6bc Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 29 Jan 2018 15:20:03 +0800 Subject: [PATCH 19/80] update gradle config --- gradle.properties | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index 2738489e..d86f6c8c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -47,6 +47,6 @@ VERSION=1 VERSION_NAME=1.2.6.4 PACKAGING_TYPE=aar useNewSupportLibrary=true -systemProp.compileSdkVersion=23 -systemProp.targetSdkVersion=23 -systemProp.buildToolsVersion=23.0.2 +systemProp.compileSdkVersion=25 +systemProp.targetSdkVersion=25 +systemProp.buildToolsVersion=25.0.3 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f783c8f2..3ca3e4e1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -27,4 +27,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip From 51b38a08bf1fb1b3b47cdd4eb9e6195cdf0514a7 Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 29 Jan 2018 16:06:32 +0800 Subject: [PATCH 20/80] update gradle --- vlayout/build.gradle | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/vlayout/build.gradle b/vlayout/build.gradle index 1a2e32cd..de87624f 100644 --- a/vlayout/build.gradle +++ b/vlayout/build.gradle @@ -24,20 +24,41 @@ apply plugin: 'com.android.library' +buildscript { + repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url "http://oss.jfrog.org/oss-snapshot-local/" } + mavenCentral() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:2.3.0' + } +} + +repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url "http://oss.jfrog.org/oss-snapshot-local/" } + jcenter() + mavenLocal() +} + + ext { bintrayRepo = 'Tangram' bintrayName = 'vlayout' - publishedGroupId = GROUP - libraryName = ARTIFACT - artifact = ARTIFACT + publishedGroupId = project.hasProperty('GROUP') ? GROUP : '' + libraryName = project.hasProperty('ARTIFACT') ? ARTIFACT : '' + artifact = project.hasProperty('ARTIFACT') ? ARTIFACT : '' libraryDescription = 'Project vlayout is a powerfull LayoutManager extension for RecyclerView, it provides a group of layouts for RecyclerView. Make it able to handle a complicate situation when grid, list and other layouts in the same recyclerview.' siteUrl = 'https://github.com/alibaba/vlayout' gitUrl = 'https://github.com/alibaba/vlayout.git' - libraryVersion = VERSION_NAME + libraryVersion = project.hasProperty('VERSION_NAME') ? VERSION_NAME : '' developerId = 'longerian' developerName = 'longerian' @@ -77,7 +98,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) // compile project(':extension') - if (useNewSupportLibrary == true) { + if (project.hasProperty('useNewSupportLibrary')) { compile 'com.android.support:recyclerview-v7:25.2.0@aar' compile('com.android.support:support-v4:25.2.0@aar') compile 'com.android.support:support-annotations:25.2.0' From a4fed5716e63fd48ff01ea9ff78a524aece5b982 Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 29 Jan 2018 16:54:46 +0800 Subject: [PATCH 21/80] update gradle, remove unused test code --- vlayout/build.gradle | 8 ++- .../android/vlayout/test/AdapterBuilder.java | 41 ----------- .../vlayout/test/LinearLayoutHelperTest.java | 72 ------------------- .../test/VirtualLayoutAdapterTest.java | 41 ----------- 4 files changed, 7 insertions(+), 155 deletions(-) delete mode 100644 vlayout/src/test/java/com/alibaba/android/vlayout/test/AdapterBuilder.java delete mode 100644 vlayout/src/test/java/com/alibaba/android/vlayout/test/LinearLayoutHelperTest.java delete mode 100644 vlayout/src/test/java/com/alibaba/android/vlayout/test/VirtualLayoutAdapterTest.java diff --git a/vlayout/build.gradle b/vlayout/build.gradle index de87624f..e439533c 100644 --- a/vlayout/build.gradle +++ b/vlayout/build.gradle @@ -92,7 +92,13 @@ android { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } } + } + } + + lintOptions { + abortOnError false + } + } dependencies { diff --git a/vlayout/src/test/java/com/alibaba/android/vlayout/test/AdapterBuilder.java b/vlayout/src/test/java/com/alibaba/android/vlayout/test/AdapterBuilder.java deleted file mode 100644 index 131a7122..00000000 --- a/vlayout/src/test/java/com/alibaba/android/vlayout/test/AdapterBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 Alibaba Group - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.alibaba.android.vlayout.test; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; - -/** - * Created by villadora on 15/8/13. - */ -public class AdapterBuilder { - public static AdapterBuilder newBuilder(Context context) { - return new AdapterBuilder(); - } - - public RecyclerView.Adapter build() { - return null; - } -} diff --git a/vlayout/src/test/java/com/alibaba/android/vlayout/test/LinearLayoutHelperTest.java b/vlayout/src/test/java/com/alibaba/android/vlayout/test/LinearLayoutHelperTest.java deleted file mode 100644 index 384fc5be..00000000 --- a/vlayout/src/test/java/com/alibaba/android/vlayout/test/LinearLayoutHelperTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 Alibaba Group - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.alibaba.android.vlayout.test; - -import android.app.Activity; -import android.support.v7.widget.RecyclerView; - -import com.alibaba.android.vlayout.VirtualLayoutManager; -import com.alibaba.android.vlayout.vlayout.BuildConfig; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLog; - -/** - * Created by villadora on 15/8/13. - */ -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) -public class LinearLayoutHelperTest { - - private Activity mActivity; - - private RecyclerView mRecyclerView; - - private VirtualLayoutManager mLayoutManager; - - @Before - public void setup() { - ShadowLog.stream = System.out; - mActivity = Robolectric.buildActivity(Activity.class).create().get(); - mRecyclerView = new RecyclerView(mActivity); - mLayoutManager = new VirtualLayoutManager(mActivity); - } - - @Test - public void test_findFirstCompletelyVisibleItem() { - RecyclerView.Adapter adapter = AdapterBuilder.newBuilder(mActivity).build(); - // Utils.setupLayoutTest(null, adapter, mLayoutManager, mRecyclerView); - - Assert.assertEquals(0, mLayoutManager.findFirstCompletelyVisibleItemPosition()); - } - -} - diff --git a/vlayout/src/test/java/com/alibaba/android/vlayout/test/VirtualLayoutAdapterTest.java b/vlayout/src/test/java/com/alibaba/android/vlayout/test/VirtualLayoutAdapterTest.java deleted file mode 100644 index 6ddb1981..00000000 --- a/vlayout/src/test/java/com/alibaba/android/vlayout/test/VirtualLayoutAdapterTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2016 Alibaba Group - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.alibaba.android.vlayout.test; - -import com.alibaba.android.vlayout.vlayout.BuildConfig; - -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -/** - * Created by villadora on 15/8/7. - */ -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class) -public class VirtualLayoutAdapterTest { - - -} From fda15d2ae6e8d70568a7ca9b72b713e93deb0148 Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 30 Jan 2018 11:55:43 +0800 Subject: [PATCH 22/80] fix npe --- .../vlayout/layout/StaggeredGridLayoutHelper.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 266c8355..358b5dbe 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -404,18 +404,18 @@ private void recycleForPreLayout(RecyclerView.Recycler recycler, LayoutStateWrap Span span = findSpan(position, child, false); if (span != null) { span.popEnd(orientationHelper); - helper.removeChildView(child); - recycler.recycleView(child); } + helper.removeChildView(child); + recycler.recycleView(child); } else { 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); } + helper.removeChildView(child); + recycler.recycleView(child); break; } } @@ -1341,7 +1341,7 @@ int invalidateAfter(int position) { } int getSpan(int position) { - if (mData == null || position >= mData.length) { + if (mData == null || position >= mData.length || position < 0) { return INVALID_SPAN_ID; } else { return mData[position]; From 4b4c4ac770101c071b6e6a89c24cb258eb9d1ded Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 5 Feb 2018 20:47:27 +0800 Subject: [PATCH 23/80] fix #295, maybe also fix #283 --- .../java/com/alibaba/android/vlayout/DelegateAdapter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java index 0ddf2085..4bb716e2 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java @@ -131,7 +131,13 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType @SuppressWarnings("unchecked") @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + Pair pair = findAdapterByPosition(position); + if (pair == null) { + return; + } + pair.second.onBindViewHolder(holder, position - pair.first.mStartPosition); + pair.second.onBindViewHolderWithOffset(holder, position - pair.first.mStartPosition, position); } @SuppressWarnings("unchecked") From f03f00192825335e963da2c7642aa79503b8ab00 Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 12 Feb 2018 11:42:03 +0800 Subject: [PATCH 24/80] update deploy script --- jcenterDeploy.gradle | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/jcenterDeploy.gradle b/jcenterDeploy.gradle index 33f55430..e1d7a7c1 100644 --- a/jcenterDeploy.gradle +++ b/jcenterDeploy.gradle @@ -86,14 +86,21 @@ artifacts { } // Bintray -//Properties properties = new Properties() -//properties.load(project.rootProject.file('local.properties').newDataInputStream()) +Properties properties = new Properties() +File localProperties = project.rootProject.file('local.properties') +if (localProperties.exists()) { + properties.load(project.rootProject.file('local.properties').newDataInputStream()) +} bintray { -// user = properties.getProperty("bintray.user") -// key = properties.getProperty("bintray.apikey") - user = project.hasProperty('bintrayUser') ? project.getProperty('bintrayUser') : "" - key = project.hasProperty('bintrayApikey') ? project.getProperty('bintrayApikey') : "" + user = properties.getProperty("bintray.user") + key = properties.getProperty("bintray.apikey") + if (!user) { + user = project.hasProperty('bintrayUser') ? project.getProperty('bintrayUser') : "" + } + if (!key) { + key = project.hasProperty('bintrayApikey') ? project.getProperty('bintrayApikey') : "" + } configurations = ['archives'] pkg { @@ -109,15 +116,23 @@ bintray { desc = libraryDescription gpg { sign = true //Determines whether to GPG sign the files. The default is false -// passphrase = properties.getProperty("bintray.gpg.password") - passphrase = project.hasProperty('bintrayGPG') ? project.getProperty('bintrayGPG') : "" + passphrase = properties.getProperty("bintray.gpg.password") + if (!passphrase) { + passphrase = project.hasProperty('bintrayGPG') ? project.getProperty('bintrayGPG') : "" + } //Optional. The passphrase for GPG signing' } mavenCentralSync { sync = true - user = project.hasProperty('bintray.oss.user') ? project.getProperty('bintray.oss.user') : "" - password = project.hasProperty('bintray.oss.password') ? project.getProperty('bintray.oss.password') : "" + user = properties.getProperty('bintray.oss.user') + if (!user) { + user = project.hasProperty('bintray.oss.user') ? project.getProperty('bintray.oss.user') : "" + } + password = properties.getProperty('bintray.oss.password') + if (!password) { + password = project.hasProperty('bintray.oss.password') ? project.getProperty('bintray.oss.password') : "" + } close = '1' } } From 2dfc4ac3aee7623d23b7307617d1974dac5201b4 Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 12 Feb 2018 14:42:01 +0800 Subject: [PATCH 25/80] fix #295, maybe also fix #283 --- .../main/java/com/alibaba/android/vlayout/DelegateAdapter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java index 4bb716e2..705c3f4e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java @@ -143,7 +143,6 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { @SuppressWarnings("unchecked") @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) { - super.onBindViewHolder(holder, position, payloads); Pair pair = findAdapterByPosition(position); if (pair == null) { return; From f2d3553863d092b0b06df34cfd9e5465ec5e0d0e Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Tue, 27 Feb 2018 16:11:29 +0800 Subject: [PATCH 26/80] Update README-ch.md --- README-ch.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README-ch.md b/README-ch.md index 7f5ac406..a2278f76 100644 --- a/README-ch.md +++ b/README-ch.md @@ -167,3 +167,6 @@ recycler.setAdapter(myAdapter); # 开源许可证 vlayout遵循MIT开源许可证协议。 + +# 微信群 +搜索帐号 longerian 获取邀请 From ee551601a8c83151028c4ce801b87678e7e7d5da Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Tue, 27 Feb 2018 16:11:43 +0800 Subject: [PATCH 27/80] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 76b41b7f..0e3a306c 100644 --- a/README.md +++ b/README.md @@ -168,3 +168,6 @@ Before you open an issue or create a pull request, please read [Contributing Gui # LICENSE Vlayout is available under the MIT license. + +# WeChatGroup +Search `longerian` to be invited in WeChat. From 80ac4a34f896dc297536da9d41e7e3441c15cb86 Mon Sep 17 00:00:00 2001 From: ivy Date: Wed, 28 Feb 2018 10:10:22 +0800 Subject: [PATCH 28/80] =?UTF-8?q?1.fix=20bug=EF=BC=88onViewAttachedToWindo?= =?UTF-8?q?w()=EF=BC=8ConViewDetachedFromWindow=EF=BC=8ConViewRecycled?= =?UTF-8?q?=EF=BC=89when=20position=20is=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/android/vlayout/DelegateAdapter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java index 705c3f4e..3b6c32dd 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java @@ -221,7 +221,7 @@ public void onViewRecycled(RecyclerView.ViewHolder holder) { super.onViewRecycled(holder); int position = holder.getPosition(); - if (position > 0) { + if (position >= 0) { Pair pair = findAdapterByPosition(position); if (pair != null) { pair.second.onViewRecycled(holder); @@ -235,7 +235,7 @@ public void onViewRecycled(RecyclerView.ViewHolder holder) { public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); int position = holder.getPosition(); - if (position > 0) { + if (position >= 0) { Pair pair = findAdapterByPosition(position); if (pair != null) { pair.second.onViewAttachedToWindow(holder); @@ -248,7 +248,7 @@ public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { super.onViewDetachedFromWindow(holder); int position = holder.getPosition(); - if (position > 0) { + if (position >= 0) { Pair pair = findAdapterByPosition(position); if (pair != null) { pair.second.onViewDetachedFromWindow(holder); From a704a4b72dbea73035328f9238beaa046162a94a Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 28 Feb 2018 11:15:28 +0800 Subject: [PATCH 29/80] update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d86f6c8c..21b925d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.6.4 +VERSION_NAME=1.2.11 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From 16cbcc53ebfd7d73966cbb8317f7ae62c530fc8c Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 2 Mar 2018 11:35:58 +0800 Subject: [PATCH 30/80] opt layout params instance in OnePlusNLayoutHelper --- .../vlayout/layout/BaseLayoutHelper.java | 6 +- .../vlayout/layout/OnePlusNLayoutHelper.java | 95 ++++++++---------- .../layout/OnePlusNLayoutHelperEx.java | 98 ++++++++----------- 3 files changed, 83 insertions(+), 116 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index b67040b0..13980db8 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -507,14 +507,14 @@ protected void handleStateOnResult(LayoutChunkResult result, View view) { /** * Helper methods to handle focus states for views - * FIXME 可变参数性能不好,会引起一次潜在的数组对象创建,在频繁滑动过程中,容易引起GC,如果只有一个View,建议调用上述方法 * @param result * @param views */ - protected void handleStateOnResult(LayoutChunkResult result, View... views) { + protected void handleStateOnResult(LayoutChunkResult result, View[] views) { if (views == null) return; - for (View view : views) { + for (int i = 0; i < views.length; i++) { + View view = views[i]; if (view == null) { continue; } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index fabfcd99..f6943687 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -30,6 +30,7 @@ import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.AnchorInfoWrapper; +import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; import android.graphics.Rect; @@ -268,7 +269,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { + private float getViewMainWeight(int index) { if (mColWeights.length > index) { return mColWeights[index]; } @@ -317,8 +318,8 @@ private int handleHeader(View header, LayoutStateWrapper layoutState, LayoutChun } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - header.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) header.getLayoutParams(); + // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, @@ -337,8 +338,7 @@ private int handleFooter(View footer, LayoutStateWrapper layoutState, LayoutChun OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - footer.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) footer.getLayoutParams(); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, @@ -355,8 +355,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); View view = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams) view.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) view.getLayoutParams(); if (!Float.isNaN(mAspectRatio)) { if (layoutInVertical) { @@ -366,7 +365,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, } } - final float weight = getViewMainWeight(lp, 0); + final float weight = getViewMainWeight(0); // fill width int widthSpec = helper.getChildMeasureSpec( @@ -384,7 +383,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.bottom, helper); - handleStateOnResult(result, null, view, null); + handleStateOnResult(result, view); mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); return mainConsumed; } @@ -395,13 +394,11 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = mChildrenViews[1]; - final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); if (layoutInVertical) { @@ -486,7 +483,7 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed = mAreaRect.right - mAreaRect.left + (hasHeader ? 0 : mMarginLeft + mPaddingRight) + (hasFooter ? 0 : mMarginRight + mPaddingRight); } - handleStateOnResult(result, null, child1, child2, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -496,19 +493,16 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[1]; final View child3 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[2]; - final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); - final ViewGroup.MarginLayoutParams lp3 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); if (layoutInVertical) { @@ -579,7 +573,7 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -590,22 +584,18 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); if (layoutInVertical) { @@ -691,7 +681,7 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, child4, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -701,26 +691,21 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); if (layoutInVertical) { @@ -819,7 +804,7 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, child4, child5, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java index 07526ced..03eea1a1 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java @@ -185,7 +185,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { + private float getViewMainWeight(int index) { if (mColWeights.length > index) { return mColWeights[index]; } @@ -228,26 +228,21 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); if (layoutInVertical) { @@ -349,7 +344,7 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -361,30 +356,24 @@ private int handSix(LayoutStateWrapper layoutState, LayoutChunkResult result, La OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[5] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); final View child6 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[5]; - final VirtualLayoutManager.LayoutParams lp6 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child6.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp6 = (VirtualLayoutManager.LayoutParams) child6.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); - final float weight6 = getViewMainWeight(lp1, 5); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); + final float weight6 = getViewMainWeight(5); if (layoutInVertical) { @@ -512,7 +501,7 @@ private int handSix(LayoutStateWrapper layoutState, LayoutChunkResult result, La // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5, child6); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -522,34 +511,27 @@ private int handSeven(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[6] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[5] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); final View child6 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[5]; - final VirtualLayoutManager.LayoutParams lp6 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child6.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp6 = (VirtualLayoutManager.LayoutParams) child6.getLayoutParams(); final View child7 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[6]; - final VirtualLayoutManager.LayoutParams lp7 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child7.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp7 = (VirtualLayoutManager.LayoutParams) child7.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); - final float weight6 = getViewMainWeight(lp1, 5); - final float weight7 = getViewMainWeight(lp1, 6); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); + final float weight6 = getViewMainWeight(5); + final float weight7 = getViewMainWeight(6); if (layoutInVertical) { @@ -677,7 +659,7 @@ private int handSeven(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5, child6); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } } From aa09e9e1ef899d8cb37d64aab75a1ac23a6f1458 Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 2 Mar 2018 14:45:18 +0800 Subject: [PATCH 31/80] use for-i instead of for-each to reduce memory alloc --- .../android/vlayout/LayoutHelperFinder.java | 6 +- .../vlayout/RangeLayoutHelperFinder.java | 47 +++++---------- .../android/vlayout/VirtualLayoutManager.java | 60 +++++++++++++------ .../layout/StaggeredGridLayoutHelper.java | 30 ++++++---- 4 files changed, 80 insertions(+), 63 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java b/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java index 76ddd28c..09f876df 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java @@ -32,7 +32,7 @@ /** * LayoutHelperFinder provides as repository of LayoutHelpers */ -public abstract class LayoutHelperFinder implements Iterable { +public abstract class LayoutHelperFinder { /** * Put layouts into the finder @@ -57,10 +57,10 @@ public abstract class LayoutHelperFinder implements Iterable { protected abstract List getLayoutHelpers(); /** - * Get iterator that in reverse order + * Get layoutHelpers that in reverse order * * @return */ - protected abstract Iterable reverse(); + protected abstract List reverse(); } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java index a151d4d5..cde8451e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java @@ -29,13 +29,11 @@ import java.util.Collections; import java.util.Comparator; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; /** - An implement of {@link LayoutHelperFinder} which finds layoutHelpers by position + * An implement of {@link LayoutHelperFinder} which finds layoutHelpers by position */ public class RangeLayoutHelperFinder extends LayoutHelperFinder { @@ -45,6 +43,9 @@ public class RangeLayoutHelperFinder extends LayoutHelperFinder { @NonNull private List mLayoutHelpers = new LinkedList<>(); + @NonNull + private List mReverseLayoutHelpers =new LinkedList<>(); + @NonNull private Comparator mLayoutHelperItemComparator = new Comparator() { @Override @@ -54,31 +55,8 @@ public int compare(LayoutHelperItem lhs, LayoutHelperItem rhs) { }; @Override - public Iterator iterator() { - return Collections.unmodifiableList(mLayoutHelpers).iterator(); - } - - @Override - protected Iterable reverse() { - final ListIterator i = mLayoutHelpers.listIterator(mLayoutHelpers.size()); - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - public boolean hasNext() { - return i.hasPrevious(); - } - - public LayoutHelper next() { - return i.previous(); - } - - public void remove() { - i.remove(); - } - }; - } - }; + protected List reverse() { + return mReverseLayoutHelpers; } /** @@ -87,12 +65,17 @@ public void remove() { @Override public void setLayouts(@Nullable List layouts) { mLayoutHelpers.clear(); + mReverseLayoutHelpers.clear(); mLayoutHelperItems.clear(); if (layouts != null) { - for (LayoutHelper helper : layouts) { + for (int i = 0, size = layouts.size(); i < size; i++) { + LayoutHelper helper = layouts.get(i); mLayoutHelpers.add(helper); mLayoutHelperItems.add(new LayoutHelperItem(helper)); } + for (int i = layouts.size() - 1; i >= 0; i--) { + mReverseLayoutHelpers.add(layouts.get(i)); + } Collections.sort(mLayoutHelperItems, mLayoutHelperItemComparator); } @@ -101,7 +84,7 @@ public void setLayouts(@Nullable List layouts) { @NonNull @Override protected List getLayoutHelpers() { - return Collections.unmodifiableList(mLayoutHelpers); + return mLayoutHelpers; } @Nullable @@ -123,8 +106,9 @@ public LayoutHelper getLayoutHelper(int position) { e = m - 1; } else if (rs.getEndPosition() < position) { s = m + 1; - } else if (rs.getStartPosition() <= position && rs.getEndPosition() >= position) + } else if (rs.getStartPosition() <= position && rs.getEndPosition() >= position) { break; + } rs = null; } @@ -132,7 +116,6 @@ public LayoutHelper getLayoutHelper(int position) { return rs == null ? null : rs.layoutHelper; } - static class LayoutHelperItem { LayoutHelperItem(LayoutHelper helper) { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 5fb17e5c..84deba6d 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -149,7 +149,9 @@ public void setHelperFinder(@NonNull final LayoutHelperFinder finder) { List helpers = new LinkedList<>(); if (this.mHelperFinder != null) { - for (LayoutHelper helper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); helpers.add(helper); } } @@ -183,7 +185,9 @@ public void setFixOffset(int left, int top, int right, int bottom) { * @param helpers group of layoutHelpers */ public void setLayoutHelpers(@Nullable List helpers) { - for (LayoutHelper helper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); oldHelpersSet.put(System.identityHashCode(helper), helper); } @@ -214,7 +218,9 @@ public void setLayoutHelpers(@Nullable List helpers) { this.mHelperFinder.setLayouts(helpers); - for (LayoutHelper helper : mHelperFinder) { + layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); newHelpersSet.put(System.identityHashCode(helper), helper); } @@ -332,7 +338,9 @@ public void onAnchorReady(RecyclerView.State state, ExposeLinearLayoutManagerEx. mTempAnchorInfoWrapper.position = anchorInfo.mPosition; mTempAnchorInfoWrapper.coordinate = anchorInfo.mCoordinate; - for (LayoutHelper layoutHelper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); layoutHelper.onRefreshLayout(state, mTempAnchorInfoWrapper, this); } } @@ -400,7 +408,9 @@ public int obtainExtraMargin(View child, boolean isLayoutEnd, boolean useAnchor) private void runPreLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { if (mNested == 0) { - for (LayoutHelper layoutHelper : mHelperFinder.reverse()) { + List reverseLayoutHelpers = mHelperFinder.reverse(); + for (int i = 0, size = reverseLayoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = reverseLayoutHelpers.get(i); layoutHelper.beforeLayout(recycler, state, this); } } @@ -414,7 +424,9 @@ private void runPostLayout(RecyclerView.Recycler recycler, RecyclerView.State st mNested = 0; final int startPosition = findFirstVisibleItemPosition(); final int endPosition = findLastVisibleItemPosition(); - for (LayoutHelper layoutHelper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); try { layoutHelper.afterLayout(recycler, state, startPosition, endPosition, scrolled, this); } catch (Exception e) { @@ -566,8 +578,10 @@ public void onScrollStateChanged(int state) { int startPosition = findFirstVisibleItemPosition(); int endPosition = findLastVisibleItemPosition(); - for (LayoutHelper helper : mHelperFinder) { - helper.onScrollStateChanged(state, startPosition, endPosition, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onScrollStateChanged(state, startPosition, endPosition, this); } } @@ -575,16 +589,20 @@ public void onScrollStateChanged(int state) { public void offsetChildrenHorizontal(int dx) { super.offsetChildrenHorizontal(dx); - for (LayoutHelper helper : mHelperFinder) { - helper.onOffsetChildrenHorizontal(dx, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onOffsetChildrenHorizontal(dx, this); } } @Override public void offsetChildrenVertical(int dy) { super.offsetChildrenVertical(dy); - for (LayoutHelper helper : mHelperFinder) { - helper.onOffsetChildrenVertical(dy, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onOffsetChildrenVertical(dy, this); } } @@ -784,8 +802,10 @@ public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCo @Override public void onItemsChanged(RecyclerView recyclerView) { - for (LayoutHelper helper : mHelperFinder) { - helper.onItemsChanged(this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onItemsChanged(this); } // setLayoutHelpers(mHelperFinder.getLayoutHelpers()); @@ -837,8 +857,10 @@ public void onAttachedToWindow(RecyclerView view) { public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) { super.onDetachedFromWindow(view, recycler); - for (LayoutHelper helper : mHelperFinder) { - helper.clear(this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.clear(this); } mRecyclerView = null; @@ -1069,8 +1091,10 @@ public List getFixedViews() { // TODO: support zIndex? List views = new LinkedList<>(); - for (LayoutHelper helper : mHelperFinder) { - View fixedView = helper.getFixedView(); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + View fixedView = layoutHelper.getFixedView(); if (fixedView != null) { views.add(fixedView); } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 358b5dbe..d1df4a88 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -359,13 +359,15 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state // reach the end of layout, cache the gap // TODO: how to retain gap if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mCachedStart != INVALID_LINE) { span.mLastEdgeStart = span.mCachedStart; } } } else { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mCachedEnd != INVALID_LINE) { span.mLastEdgeEnd = span.mCachedEnd; } @@ -594,7 +596,8 @@ private void checkForGaps() { //FIXME do not clear loopup, may cause lane error while scroll //mLazySpanLookup.clear(); - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.setLine(alignLine); } @@ -619,7 +622,8 @@ private View hasGapsToFix(VirtualLayoutManager layoutManager, final int position BitSet mSpansToCheck = new BitSet(mNumLanes); mSpansToCheck.set(0, mNumLanes, true); - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mViews.size() != 0 && checkSpanForGap(span, layoutManager, alignLine)) { return layoutManager.getReverseLayout() ? span.mViews.get(span.mViews.size() - 1) : span.mViews.get(0); } @@ -926,7 +930,8 @@ public void onRefreshLayout(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "onRefreshLayout span.clear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.clear(); } } @@ -959,13 +964,15 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.clear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.clear(); span.setLine(anchorInfo.coordinate); } } else { int anchorPos = anchorInfo.layoutFromEnd ? Integer.MIN_VALUE : Integer.MAX_VALUE; - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (!span.mViews.isEmpty()) { if (anchorInfo.layoutFromEnd) { View view = span.mViews.get(span.mViews.size() - 1); @@ -1017,7 +1024,8 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.cacheReferenceLineAndClear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.cacheReferenceLineAndClear(helper.getReverseLayout() ^ anchorInfo.layoutFromEnd, offset, orientationHelper); } } @@ -1047,7 +1055,8 @@ public void onRestoreInstanceState(Bundle bundle) { public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { super.onOffsetChildrenVertical(dy, helper); if (helper.getOrientation() == VERTICAL) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.onOffset(dy); } } @@ -1057,7 +1066,8 @@ public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { public void onOffsetChildrenHorizontal(int dx, LayoutManagerHelper helper) { super.onOffsetChildrenHorizontal(dx, helper); if (helper.getOrientation() == HORIZONTAL) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.onOffset(dx); } } From a8567e16a244a690fbb12e522083bbfa314b42d8 Mon Sep 17 00:00:00 2001 From: LiuHe Date: Mon, 5 Mar 2018 18:07:47 +0800 Subject: [PATCH 32/80] Update README-ch.md --- README-ch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-ch.md b/README-ch.md index a2278f76..4684fbbe 100644 --- a/README-ch.md +++ b/README-ch.md @@ -21,7 +21,7 @@ VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一 ## 设计思路 -通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比系统自带的LinearLayoutManager、aridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。 +通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比系统自带的LinearLayoutManager、GridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。 ## 主要功能 From a6918f67e9ceef00e71001bc49791d9f51ff9736 Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 2 Mar 2018 11:35:58 +0800 Subject: [PATCH 33/80] opt layout params instance in OnePlusNLayoutHelper --- .../vlayout/layout/BaseLayoutHelper.java | 6 +- .../vlayout/layout/OnePlusNLayoutHelper.java | 95 ++++++++---------- .../layout/OnePlusNLayoutHelperEx.java | 98 ++++++++----------- 3 files changed, 83 insertions(+), 116 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index b67040b0..13980db8 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -507,14 +507,14 @@ protected void handleStateOnResult(LayoutChunkResult result, View view) { /** * Helper methods to handle focus states for views - * FIXME 可变参数性能不好,会引起一次潜在的数组对象创建,在频繁滑动过程中,容易引起GC,如果只有一个View,建议调用上述方法 * @param result * @param views */ - protected void handleStateOnResult(LayoutChunkResult result, View... views) { + protected void handleStateOnResult(LayoutChunkResult result, View[] views) { if (views == null) return; - for (View view : views) { + for (int i = 0; i < views.length; i++) { + View view = views[i]; if (view == null) { continue; } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java index fabfcd99..f6943687 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelper.java @@ -30,6 +30,7 @@ import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.AnchorInfoWrapper; +import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; import android.graphics.Rect; @@ -268,7 +269,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { + private float getViewMainWeight(int index) { if (mColWeights.length > index) { return mColWeights[index]; } @@ -317,8 +318,8 @@ private int handleHeader(View header, LayoutStateWrapper layoutState, LayoutChun } OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - header.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) header.getLayoutParams(); + // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, @@ -337,8 +338,7 @@ private int handleFooter(View footer, LayoutStateWrapper layoutState, LayoutChun OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - footer.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) footer.getLayoutParams(); // fill width int widthSpec = helper.getChildMeasureSpec(parentWidth - parentHPadding, @@ -355,8 +355,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); View view = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams) view.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp = (LayoutParams) view.getLayoutParams(); if (!Float.isNaN(mAspectRatio)) { if (layoutInVertical) { @@ -366,7 +365,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, } } - final float weight = getViewMainWeight(lp, 0); + final float weight = getViewMainWeight(0); // fill width int widthSpec = helper.getChildMeasureSpec( @@ -384,7 +383,7 @@ private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, layoutChildWithMargin(view, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.bottom, helper); - handleStateOnResult(result, null, view, null); + handleStateOnResult(result, view); mainConsumed = mAreaRect.bottom - mAreaRect.top + (hasHeader ? 0 : mMarginTop + mPaddingTop) + (hasFooter ? 0 : mMarginBottom + mPaddingBottom); return mainConsumed; } @@ -395,13 +394,11 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = mChildrenViews[1]; - final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); if (layoutInVertical) { @@ -486,7 +483,7 @@ private int handleTwo(LayoutStateWrapper layoutState, LayoutChunkResult result, mainConsumed = mAreaRect.right - mAreaRect.left + (hasHeader ? 0 : mMarginLeft + mPaddingRight) + (hasFooter ? 0 : mMarginRight + mPaddingRight); } - handleStateOnResult(result, null, child1, child2, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -496,19 +493,16 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final ViewGroup.MarginLayoutParams lp1 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[1]; final View child3 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[2]; - final ViewGroup.MarginLayoutParams lp2 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child2.getLayoutParams()); - final ViewGroup.MarginLayoutParams lp3 = new ViewGroup.MarginLayoutParams( - (ViewGroup.MarginLayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); if (layoutInVertical) { @@ -579,7 +573,7 @@ private int handleThree(LayoutStateWrapper layoutState, LayoutChunkResult result // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -590,22 +584,18 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); if (layoutInVertical) { @@ -691,7 +681,7 @@ private int handleFour(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, child4, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -701,26 +691,21 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); if (layoutInVertical) { @@ -819,7 +804,7 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, null, child1, child2, child3, child4, child5, null); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java index 07526ced..03eea1a1 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/OnePlusNLayoutHelperEx.java @@ -185,7 +185,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } - private float getViewMainWeight(ViewGroup.MarginLayoutParams params, int index) { + private float getViewMainWeight(int index) { if (mColWeights.length > index) { return mColWeights[index]; } @@ -228,26 +228,21 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); if (layoutInVertical) { @@ -349,7 +344,7 @@ private int handleFive(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -361,30 +356,24 @@ private int handSix(LayoutStateWrapper layoutState, LayoutChunkResult result, La OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[5] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); final View child6 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[5]; - final VirtualLayoutManager.LayoutParams lp6 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child6.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp6 = (VirtualLayoutManager.LayoutParams) child6.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); - final float weight6 = getViewMainWeight(lp1, 5); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); + final float weight6 = getViewMainWeight(5); if (layoutInVertical) { @@ -512,7 +501,7 @@ private int handSix(LayoutStateWrapper layoutState, LayoutChunkResult result, La // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5, child6); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } @@ -522,34 +511,27 @@ private int handSeven(LayoutStateWrapper layoutState, LayoutChunkResult result, OrientationHelperEx orientationHelper = helper.getMainOrientationHelper(); final View child1 = mChildrenViews[0]; - final VirtualLayoutManager.LayoutParams lp1 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child1.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp1 = (VirtualLayoutManager.LayoutParams) child1.getLayoutParams(); final View child2 = helper.getReverseLayout() ? mChildrenViews[6] : mChildrenViews[1]; - final VirtualLayoutManager.LayoutParams lp2 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child2.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp2 = (VirtualLayoutManager.LayoutParams) child2.getLayoutParams(); final View child3 = helper.getReverseLayout() ? mChildrenViews[5] : mChildrenViews[2]; - final VirtualLayoutManager.LayoutParams lp3 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child3.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp3 = (VirtualLayoutManager.LayoutParams) child3.getLayoutParams(); final View child4 = helper.getReverseLayout() ? mChildrenViews[4] : mChildrenViews[3]; - final VirtualLayoutManager.LayoutParams lp4 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child4.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp4 = (VirtualLayoutManager.LayoutParams) child4.getLayoutParams(); final View child5 = helper.getReverseLayout() ? mChildrenViews[3] : mChildrenViews[4]; - final VirtualLayoutManager.LayoutParams lp5 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child5.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp5 = (VirtualLayoutManager.LayoutParams) child5.getLayoutParams(); final View child6 = helper.getReverseLayout() ? mChildrenViews[2] : mChildrenViews[5]; - final VirtualLayoutManager.LayoutParams lp6 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child6.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp6 = (VirtualLayoutManager.LayoutParams) child6.getLayoutParams(); final View child7 = helper.getReverseLayout() ? mChildrenViews[1] : mChildrenViews[6]; - final VirtualLayoutManager.LayoutParams lp7 = new VirtualLayoutManager.LayoutParams( - (VirtualLayoutManager.LayoutParams)child7.getLayoutParams()); + final VirtualLayoutManager.LayoutParams lp7 = (VirtualLayoutManager.LayoutParams) child7.getLayoutParams(); - final float weight1 = getViewMainWeight(lp1, 0); - final float weight2 = getViewMainWeight(lp1, 1); - final float weight3 = getViewMainWeight(lp1, 2); - final float weight4 = getViewMainWeight(lp1, 3); - final float weight5 = getViewMainWeight(lp1, 4); - final float weight6 = getViewMainWeight(lp1, 5); - final float weight7 = getViewMainWeight(lp1, 6); + final float weight1 = getViewMainWeight(0); + final float weight2 = getViewMainWeight(1); + final float weight3 = getViewMainWeight(2); + final float weight4 = getViewMainWeight(3); + final float weight5 = getViewMainWeight(4); + final float weight6 = getViewMainWeight(5); + final float weight7 = getViewMainWeight(6); if (layoutInVertical) { @@ -677,7 +659,7 @@ private int handSeven(LayoutStateWrapper layoutState, LayoutChunkResult result, // TODO: horizontal support } - handleStateOnResult(result, child1, child2, child3, child4, child5, child6); + handleStateOnResult(result, mChildrenViews); return mainConsumed; } } From 24629ce0b3a71c4c0578b2629e7518d59ef9cea6 Mon Sep 17 00:00:00 2001 From: longerian Date: Fri, 2 Mar 2018 14:45:18 +0800 Subject: [PATCH 34/80] use for-i instead of for-each to reduce memory alloc --- .../android/vlayout/LayoutHelperFinder.java | 6 +- .../vlayout/RangeLayoutHelperFinder.java | 47 +++++---------- .../android/vlayout/VirtualLayoutManager.java | 60 +++++++++++++------ .../layout/StaggeredGridLayoutHelper.java | 30 ++++++---- 4 files changed, 80 insertions(+), 63 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java b/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java index 76ddd28c..09f876df 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/LayoutHelperFinder.java @@ -32,7 +32,7 @@ /** * LayoutHelperFinder provides as repository of LayoutHelpers */ -public abstract class LayoutHelperFinder implements Iterable { +public abstract class LayoutHelperFinder { /** * Put layouts into the finder @@ -57,10 +57,10 @@ public abstract class LayoutHelperFinder implements Iterable { protected abstract List getLayoutHelpers(); /** - * Get iterator that in reverse order + * Get layoutHelpers that in reverse order * * @return */ - protected abstract Iterable reverse(); + protected abstract List reverse(); } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java index a151d4d5..cde8451e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java @@ -29,13 +29,11 @@ import java.util.Collections; import java.util.Comparator; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; /** - An implement of {@link LayoutHelperFinder} which finds layoutHelpers by position + * An implement of {@link LayoutHelperFinder} which finds layoutHelpers by position */ public class RangeLayoutHelperFinder extends LayoutHelperFinder { @@ -45,6 +43,9 @@ public class RangeLayoutHelperFinder extends LayoutHelperFinder { @NonNull private List mLayoutHelpers = new LinkedList<>(); + @NonNull + private List mReverseLayoutHelpers =new LinkedList<>(); + @NonNull private Comparator mLayoutHelperItemComparator = new Comparator() { @Override @@ -54,31 +55,8 @@ public int compare(LayoutHelperItem lhs, LayoutHelperItem rhs) { }; @Override - public Iterator iterator() { - return Collections.unmodifiableList(mLayoutHelpers).iterator(); - } - - @Override - protected Iterable reverse() { - final ListIterator i = mLayoutHelpers.listIterator(mLayoutHelpers.size()); - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - public boolean hasNext() { - return i.hasPrevious(); - } - - public LayoutHelper next() { - return i.previous(); - } - - public void remove() { - i.remove(); - } - }; - } - }; + protected List reverse() { + return mReverseLayoutHelpers; } /** @@ -87,12 +65,17 @@ public void remove() { @Override public void setLayouts(@Nullable List layouts) { mLayoutHelpers.clear(); + mReverseLayoutHelpers.clear(); mLayoutHelperItems.clear(); if (layouts != null) { - for (LayoutHelper helper : layouts) { + for (int i = 0, size = layouts.size(); i < size; i++) { + LayoutHelper helper = layouts.get(i); mLayoutHelpers.add(helper); mLayoutHelperItems.add(new LayoutHelperItem(helper)); } + for (int i = layouts.size() - 1; i >= 0; i--) { + mReverseLayoutHelpers.add(layouts.get(i)); + } Collections.sort(mLayoutHelperItems, mLayoutHelperItemComparator); } @@ -101,7 +84,7 @@ public void setLayouts(@Nullable List layouts) { @NonNull @Override protected List getLayoutHelpers() { - return Collections.unmodifiableList(mLayoutHelpers); + return mLayoutHelpers; } @Nullable @@ -123,8 +106,9 @@ public LayoutHelper getLayoutHelper(int position) { e = m - 1; } else if (rs.getEndPosition() < position) { s = m + 1; - } else if (rs.getStartPosition() <= position && rs.getEndPosition() >= position) + } else if (rs.getStartPosition() <= position && rs.getEndPosition() >= position) { break; + } rs = null; } @@ -132,7 +116,6 @@ public LayoutHelper getLayoutHelper(int position) { return rs == null ? null : rs.layoutHelper; } - static class LayoutHelperItem { LayoutHelperItem(LayoutHelper helper) { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 5fb17e5c..84deba6d 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -149,7 +149,9 @@ public void setHelperFinder(@NonNull final LayoutHelperFinder finder) { List helpers = new LinkedList<>(); if (this.mHelperFinder != null) { - for (LayoutHelper helper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); helpers.add(helper); } } @@ -183,7 +185,9 @@ public void setFixOffset(int left, int top, int right, int bottom) { * @param helpers group of layoutHelpers */ public void setLayoutHelpers(@Nullable List helpers) { - for (LayoutHelper helper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); oldHelpersSet.put(System.identityHashCode(helper), helper); } @@ -214,7 +218,9 @@ public void setLayoutHelpers(@Nullable List helpers) { this.mHelperFinder.setLayouts(helpers); - for (LayoutHelper helper : mHelperFinder) { + layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper helper = layoutHelpers.get(i); newHelpersSet.put(System.identityHashCode(helper), helper); } @@ -332,7 +338,9 @@ public void onAnchorReady(RecyclerView.State state, ExposeLinearLayoutManagerEx. mTempAnchorInfoWrapper.position = anchorInfo.mPosition; mTempAnchorInfoWrapper.coordinate = anchorInfo.mCoordinate; - for (LayoutHelper layoutHelper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); layoutHelper.onRefreshLayout(state, mTempAnchorInfoWrapper, this); } } @@ -400,7 +408,9 @@ public int obtainExtraMargin(View child, boolean isLayoutEnd, boolean useAnchor) private void runPreLayout(RecyclerView.Recycler recycler, RecyclerView.State state) { if (mNested == 0) { - for (LayoutHelper layoutHelper : mHelperFinder.reverse()) { + List reverseLayoutHelpers = mHelperFinder.reverse(); + for (int i = 0, size = reverseLayoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = reverseLayoutHelpers.get(i); layoutHelper.beforeLayout(recycler, state, this); } } @@ -414,7 +424,9 @@ private void runPostLayout(RecyclerView.Recycler recycler, RecyclerView.State st mNested = 0; final int startPosition = findFirstVisibleItemPosition(); final int endPosition = findLastVisibleItemPosition(); - for (LayoutHelper layoutHelper : mHelperFinder) { + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); try { layoutHelper.afterLayout(recycler, state, startPosition, endPosition, scrolled, this); } catch (Exception e) { @@ -566,8 +578,10 @@ public void onScrollStateChanged(int state) { int startPosition = findFirstVisibleItemPosition(); int endPosition = findLastVisibleItemPosition(); - for (LayoutHelper helper : mHelperFinder) { - helper.onScrollStateChanged(state, startPosition, endPosition, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onScrollStateChanged(state, startPosition, endPosition, this); } } @@ -575,16 +589,20 @@ public void onScrollStateChanged(int state) { public void offsetChildrenHorizontal(int dx) { super.offsetChildrenHorizontal(dx); - for (LayoutHelper helper : mHelperFinder) { - helper.onOffsetChildrenHorizontal(dx, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onOffsetChildrenHorizontal(dx, this); } } @Override public void offsetChildrenVertical(int dy) { super.offsetChildrenVertical(dy); - for (LayoutHelper helper : mHelperFinder) { - helper.onOffsetChildrenVertical(dy, this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onOffsetChildrenVertical(dy, this); } } @@ -784,8 +802,10 @@ public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCo @Override public void onItemsChanged(RecyclerView recyclerView) { - for (LayoutHelper helper : mHelperFinder) { - helper.onItemsChanged(this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.onItemsChanged(this); } // setLayoutHelpers(mHelperFinder.getLayoutHelpers()); @@ -837,8 +857,10 @@ public void onAttachedToWindow(RecyclerView view) { public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) { super.onDetachedFromWindow(view, recycler); - for (LayoutHelper helper : mHelperFinder) { - helper.clear(this); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + layoutHelper.clear(this); } mRecyclerView = null; @@ -1069,8 +1091,10 @@ public List getFixedViews() { // TODO: support zIndex? List views = new LinkedList<>(); - for (LayoutHelper helper : mHelperFinder) { - View fixedView = helper.getFixedView(); + List layoutHelpers = mHelperFinder.getLayoutHelpers(); + for (int i = 0, size = layoutHelpers.size(); i < size; i++) { + LayoutHelper layoutHelper = layoutHelpers.get(i); + View fixedView = layoutHelper.getFixedView(); if (fixedView != null) { views.add(fixedView); } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 358b5dbe..d1df4a88 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -359,13 +359,15 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state // reach the end of layout, cache the gap // TODO: how to retain gap if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mCachedStart != INVALID_LINE) { span.mLastEdgeStart = span.mCachedStart; } } } else { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mCachedEnd != INVALID_LINE) { span.mLastEdgeEnd = span.mCachedEnd; } @@ -594,7 +596,8 @@ private void checkForGaps() { //FIXME do not clear loopup, may cause lane error while scroll //mLazySpanLookup.clear(); - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.setLine(alignLine); } @@ -619,7 +622,8 @@ private View hasGapsToFix(VirtualLayoutManager layoutManager, final int position BitSet mSpansToCheck = new BitSet(mNumLanes); mSpansToCheck.set(0, mNumLanes, true); - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (span.mViews.size() != 0 && checkSpanForGap(span, layoutManager, alignLine)) { return layoutManager.getReverseLayout() ? span.mViews.get(span.mViews.size() - 1) : span.mViews.get(0); } @@ -926,7 +930,8 @@ public void onRefreshLayout(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "onRefreshLayout span.clear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.clear(); } } @@ -959,13 +964,15 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.clear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.clear(); span.setLine(anchorInfo.coordinate); } } else { int anchorPos = anchorInfo.layoutFromEnd ? Integer.MIN_VALUE : Integer.MAX_VALUE; - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; if (!span.mViews.isEmpty()) { if (anchorInfo.layoutFromEnd) { View view = span.mViews.get(span.mViews.size() - 1); @@ -1017,7 +1024,8 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.cacheReferenceLineAndClear()"); } - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.cacheReferenceLineAndClear(helper.getReverseLayout() ^ anchorInfo.layoutFromEnd, offset, orientationHelper); } } @@ -1047,7 +1055,8 @@ public void onRestoreInstanceState(Bundle bundle) { public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { super.onOffsetChildrenVertical(dy, helper); if (helper.getOrientation() == VERTICAL) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.onOffset(dy); } } @@ -1057,7 +1066,8 @@ public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { public void onOffsetChildrenHorizontal(int dx, LayoutManagerHelper helper) { super.onOffsetChildrenHorizontal(dx, helper); if (helper.getOrientation() == HORIZONTAL) { - for (Span span : mSpans) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; span.onOffset(dx); } } From f09df7ffe597e3b481c1d58b170bf9ea872e07aa Mon Sep 17 00:00:00 2001 From: longerian Date: Mon, 12 Mar 2018 14:09:49 +0800 Subject: [PATCH 35/80] update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 21b925d4..331c3a8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.11 +VERSION_NAME=1.2.12 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From b066df078317491ff486bde8cdbe54f997ff453d Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 21 Mar 2018 11:13:54 +0800 Subject: [PATCH 36/80] Update VLayoutFAQ.md --- docs/VLayoutFAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/VLayoutFAQ.md b/docs/VLayoutFAQ.md index 8781e6a0..d4028eef 100644 --- a/docs/VLayoutFAQ.md +++ b/docs/VLayoutFAQ.md @@ -13,7 +13,7 @@ 因此如果没有处理好这一点,会导致 `ViewHolder` 的类型转换异常等 bug。有一篇更加详细的资料可参考:[PairFunction](http://pingguohe.net/2017/05/03/the-beauty-of-math-in-vlayout.html) -补充:后来发现一个 bug,当 `hasConsistItemType=true`,在同一位置数据变化,前后构造了不一样的 Adapter,它们返回的 itemType 一样,也会导致类型转换出错,详见:[#182](https://github.com/alibaba/vlayout/issues/182),目前采用人工保证返回不同的 itemType 来规避。 +补充:后来发现一个 bug,当 `hasConsistItemType=false`,在同一位置数据变化,前后构造了不一样的 Adapter,它们返回的 itemType 一样,也会导致类型转换出错,详见:[#182](https://github.com/alibaba/vlayout/issues/182),目前采用人工保证返回不同的 itemType 来规避。 ## 设置每种类型回收复用池的大小 在 README 里写了这么一段 demo:`viewPool.setMaxRecycledViews(0, 10);`,很多人误以为只要这么设置就可以了,实际上有多少种类型的 itemType,就得为它们分别设置复用池大小。比如: From 3ce5a5cd649c9960836d6259e8c860aaa41f73c9 Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 4 Apr 2018 10:43:19 +0800 Subject: [PATCH 37/80] fix recyclerview's crash in StikcyLayoutHelper, FloatLayoutHelper, FixLayoutHelper --- .../com/alibaba/android/vlayout/VirtualLayoutManager.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 84deba6d..fa29833b 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -1454,8 +1454,11 @@ public View findViewByPosition(int position) { @Override public void recycleView(View view) { if (mRecyclerView != null) { - RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(view); - mRecyclerView.getRecycledViewPool().putRecycledView(holder); + ViewParent parent = view.getParent(); + if (parent != null && parent == mRecyclerView) { + RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(view); + mRecyclerView.getRecycledViewPool().putRecycledView(holder); + } } } From 3f659d87c27ec9796feb99ad4a72d00efe824abd Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 4 Apr 2018 10:56:58 +0800 Subject: [PATCH 38/80] update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 331c3a8e..021f2cc5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.12 +VERSION_NAME=1.2.13 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From a885e21eef6e472328ba802ff6c08a4e64d963ea Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 4 Apr 2018 11:00:34 +0800 Subject: [PATCH 39/80] Update README-ch.md --- README-ch.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README-ch.md b/README-ch.md index 4684fbbe..db91c5b9 100644 --- a/README-ch.md +++ b/README-ch.md @@ -42,6 +42,8 @@ VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一 ## 使用 +**虽然 vlayout 布局灵活,然而 API 相对原始,手工维护数据及 LayoutHelper 比较麻烦,强烈建议大家使用 [Tangram-Android](https://github.com/alibaba/Tangram-Android) 来间接使用 vlayout,Tangram 具备 vlayout 里所有的功能,且隐藏了细节,通过数据配置即可搭建页面,能避免绝大多数 Issue 里提到的问题,而且重大更新维护主要基于 Tangram,包括局部刷新、响应式接口等。** + 版本请参考 [release 说明](https://github.com/alibaba/vlayout/releases)里的最新版本,最新的 aar 都会发布到 jcenter 和 MavenCentral 上,确保配置了这两个仓库源,然后引入aar依赖: ``` gradle From 2397c0280f5b380e4089ad666dc11680204a2b3b Mon Sep 17 00:00:00 2001 From: HarrisonXi Date: Mon, 9 Apr 2018 15:39:52 +0800 Subject: [PATCH 40/80] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e3a306c..772b8b01 100644 --- a/README.md +++ b/README.md @@ -170,4 +170,7 @@ Before you open an issue or create a pull request, please read [Contributing Gui Vlayout is available under the MIT license. # WeChatGroup -Search `longerian` to be invited in WeChat. + +![](https://img.alicdn.com/tfs/TB11_2_kbSYBuNjSspiXXXNzpXa-167-167.png) + +Search `tangram_` or scan the QR code above to be invited in WeChat. From 0ffa2630eef362c1e0a073fe82193295a68325e1 Mon Sep 17 00:00:00 2001 From: HarrisonXi Date: Mon, 9 Apr 2018 15:41:12 +0800 Subject: [PATCH 41/80] Update README-ch.md --- README-ch.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README-ch.md b/README-ch.md index db91c5b9..c34404b0 100644 --- a/README-ch.md +++ b/README-ch.md @@ -171,4 +171,7 @@ recycler.setAdapter(myAdapter); vlayout遵循MIT开源许可证协议。 # 微信群 -搜索帐号 longerian 获取邀请 + +![](https://img.alicdn.com/tfs/TB11_2_kbSYBuNjSspiXXXNzpXa-167-167.png) + +搜索 `tangram_` 或者扫描以上二维码添加 Tangram 为好友,以便我们邀请你入群。 From 122f13dec281d6fe91c0c517653cfaecf12592c9 Mon Sep 17 00:00:00 2001 From: A Chinese Developer Date: Mon, 9 Apr 2018 17:21:38 +0800 Subject: [PATCH 42/80] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86DelegateAdapte?= =?UTF-8?q?r.SimpleViewAdapter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/alibaba/android/vlayout/DelegateAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java index 3b6c32dd..1373c750 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/DelegateAdapter.java @@ -636,7 +636,7 @@ public SimpleViewAdapter(@NonNull View view) { @Override public LayoutHelper onCreateLayoutHelper() { - return new SingleLayoutHelper(); + return mLayoutHelper; } @Override From 967dceacb1b9b851d838cdd2a9d2c5f403eea978 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 3 May 2018 09:46:52 +0800 Subject: [PATCH 43/80] =?UTF-8?q?Fix=20#342=EF=BC=8Cbackground=20color=20n?= =?UTF-8?q?ot=20work=20in=20StickyLayoutHelper.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/android/vlayout/layout/StickyLayoutHelper.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index 8dad360d..cc35fecb 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -291,6 +291,10 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state } else { fixLayoutStateInCase2(orientationHelper, recycler, startPosition, endPosition, helper); } + + if (mFixView != null){ + mFixView.setBackgroundColor(mBgColor); + } } private void fixLayoutStateFromAbnormal2Normal(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, From bb7a288969f70f6632e7f693f4b51fa98771ec7c Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 3 May 2018 11:05:45 +0800 Subject: [PATCH 44/80] Make recycle offset work whether layout from start or from end. --- .../alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java index 59ca1ca5..9e36a0f7 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java @@ -1155,8 +1155,7 @@ protected int fill(RecyclerView.Recycler recycler, LayoutState layoutState, } recycleByLayoutStateExpose(recycler, layoutState); } - int remainingSpace = layoutState.mAvailable + layoutState.mExtra + ( - layoutState.mLayoutDirection == LayoutState.LAYOUT_START ? 0 : recycleOffset); //FIXME opt here to fix bg and shake + int remainingSpace = layoutState.mAvailable + layoutState.mExtra + recycleOffset; while (remainingSpace > 0 && layoutState.hasMore(state)) { layoutChunkResultCache.resetInternal(); layoutChunk(recycler, state, layoutState, layoutChunkResultCache); From 56495651d8f7809f0cc04ace8ba2f341bb03f276 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 7 May 2018 19:29:26 +0800 Subject: [PATCH 45/80] Add ViewLifeCycleHelper and ViewLifeCycleListener to invoke correct view life cycle when call VirtualLayoutManager#setRecycleOffset. --- .../android/vlayout/VirtualLayoutManager.java | 24 ++- .../vlayout/extend/ViewLifeCycleHelper.java | 148 ++++++++++++++++++ .../vlayout/extend/ViewLifeCycleListener.java | 13 ++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java create mode 100644 vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleListener.java diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index fa29833b..075dd827 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -32,6 +32,8 @@ import java.util.List; import java.util.Map; +import com.alibaba.android.vlayout.extend.ViewLifeCycleHelper; +import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; import com.alibaba.android.vlayout.layout.BaseLayoutHelper; import com.alibaba.android.vlayout.layout.DefaultLayoutHelper; import com.alibaba.android.vlayout.layout.FixAreaAdjuster; @@ -94,6 +96,7 @@ public static void enableDebugging(boolean isDebug) { private int mMaxMeasureSize = -1; + private ViewLifeCycleHelper mViewLifeCycleHelper; public VirtualLayoutManager(@NonNull final Context context) { this(context, VERTICAL); @@ -435,6 +438,10 @@ private void runPostLayout(RecyclerView.Recycler recycler, RecyclerView.State st } } } + + if (null != mViewLifeCycleHelper) { + mViewLifeCycleHelper.checkViewStatusInScreen(); + } } } @@ -604,6 +611,21 @@ public void offsetChildrenVertical(int dy) { LayoutHelper layoutHelper = layoutHelpers.get(i); layoutHelper.onOffsetChildrenVertical(dy, this); } + + if (null != mViewLifeCycleHelper) { + mViewLifeCycleHelper.checkViewStatusInScreen(); + } + } + + public void setViewLifeCycleListener(@NonNull ViewLifeCycleListener viewLifeCycleListener) { + if (null == viewLifeCycleListener) { + throw new IllegalArgumentException("ViewLifeCycleListener should not be null!"); + } + mViewLifeCycleHelper = new ViewLifeCycleHelper(this, viewLifeCycleListener); + } + + public int getVirtualLayoutDirection() { + return mLayoutState.mLayoutDirection; } private LayoutStateWrapper mTempLayoutStateWrapper = new LayoutStateWrapper(); @@ -1399,7 +1421,7 @@ private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int if (getOrientation() == VERTICAL) { widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mDecorInsets.left, - lp.rightMargin + mDecorInsets.right); + lp.rightMargin + mDecorInsets.right); } if (getOrientation() == HORIZONTAL) { heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top, diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java new file mode 100644 index 00000000..ef2a904c --- /dev/null +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java @@ -0,0 +1,148 @@ +package com.alibaba.android.vlayout.extend; + +import android.support.annotation.NonNull; +import android.support.v4.util.ArrayMap; +import android.view.View; + +import com.alibaba.android.vlayout.VirtualLayoutManager; + +public class ViewLifeCycleHelper { + public enum STATUS { + APPEARING, + APPEARED, + DISAPPEARING, + DISAPPEARED + } + + private ArrayMap mViewStatusMap = new ArrayMap<>(); + + private ViewLifeCycleListener mViewLifeCycleListener; + + private VirtualLayoutManager mVirtualLayoutManager; + + private int scrHeight; + + public ViewLifeCycleHelper(VirtualLayoutManager virtualLayoutManager, @NonNull ViewLifeCycleListener mViewLifeCycleListener) { + this.mViewLifeCycleListener = mViewLifeCycleListener; + this.mVirtualLayoutManager = virtualLayoutManager; + } + + public void checkViewStatusInScreen() { + for (int i = 0; i < mVirtualLayoutManager.getChildCount(); i++) { + View view = mVirtualLayoutManager.getChildAt(i); + if (scrHeight == 0) { + scrHeight = view.getContext().getResources().getDisplayMetrics().heightPixels; + } +// Log.e("huang", "checkViewStatusInScreen: view=" + view.getTag(R.id.tag_layout_helper_bg) + " rect=" + rect.toString()); + + if (mVirtualLayoutManager.getVirtualLayoutDirection() == VirtualLayoutManager.LayoutState.LAYOUT_END) { + if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyDisAppear(view)) { +// Log.e("huang", "LAYOUT_END checkViewDisAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + setViewDisappearing(view); + } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyAppear(view)) { +// Log.e("huang", "LAYOUT_END checkViewAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + setViewAppearing(view); + } + } else { + if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyAppear(view)) { +// Log.e("huang", "LAYOUT_START checkViewAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + setViewAppearing(view); + } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyDisAppear(view)) { +// Log.e("huang", "LAYOUT_START checkViewDisAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + setViewDisappearing(view); + } + } + + if (view.getTop() > 0 && view.getBottom() < scrHeight) { + // fully in screen + + if (isViewReadyAppear(view)) { + // if not appeared, call appear + setViewAppearing(view); +// Log.e("huang", "Add appear: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); + + } else { + if (getViewStatus(view) != STATUS.APPEARED) { + setViewAppeared(view); +// Log.e("huang", "Appeared: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); + } + } + } else if (view.getBottom() < 0 || view.getTop() > scrHeight) { + // not in screen + if (isViewReadyDisAppear(view)) { + // if not disappeared, call disappear + setViewDisappearing(view); +// Log.e("huang", "Add disappear:" + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); + + } else { + if (getViewStatus(view) != STATUS.DISAPPEARED) { + setViewDisappeared(view); +// Log.e("huang", "Disappeared: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); + } + } + } + } + } + + private STATUS getViewStatus(View view) { + if (!mViewStatusMap.containsKey(view)) { + mViewStatusMap.put(view, STATUS.DISAPPEARED); + return STATUS.DISAPPEARED; + } + return mViewStatusMap.get(view); + } + + private void setViewstatus(View view, STATUS status) { + mViewStatusMap.put(view, status); + } + + private boolean isViewReadyAppear(View view) { + return getViewStatus(view) == STATUS.DISAPPEARED; + } + + private void setViewAppearing(View view) { + if (getViewStatus(view) == STATUS.APPEARING) { + return; + } + + setViewstatus(view, STATUS.APPEARING); + if (null != mViewLifeCycleListener) { + mViewLifeCycleListener.onAppearing(view); + } + } + + private void setViewAppeared(View view) { + if (getViewStatus(view) == STATUS.APPEARED) { + return; + } + setViewstatus(view, STATUS.APPEARED); + if (null != mViewLifeCycleListener) { + mViewLifeCycleListener.onAppeared(view); + } + } + + private boolean isViewReadyDisAppear(View view) { + return getViewStatus(view) == STATUS.APPEARED; + } + + private void setViewDisappearing(View view) { + if (getViewStatus(view) == STATUS.DISAPPEARING) { + return; + } + + setViewstatus(view, STATUS.DISAPPEARING); + if (null != mViewLifeCycleListener) { + mViewLifeCycleListener.onDisappearing(view); + } + } + + private void setViewDisappeared(View view) { + if (getViewStatus(view) == STATUS.DISAPPEARED) { + return; + } + setViewstatus(view, STATUS.DISAPPEARED); + if (null != mViewLifeCycleListener) { + mViewLifeCycleListener.onDisappeared(view); + } + } +} diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleListener.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleListener.java new file mode 100644 index 00000000..21e12114 --- /dev/null +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleListener.java @@ -0,0 +1,13 @@ +package com.alibaba.android.vlayout.extend; + +import android.view.View; + +public interface ViewLifeCycleListener { + void onAppearing(View view); + + void onDisappearing(View view); + + void onAppeared(View view); + + void onDisappeared(View view); +} From 03634c0233e4c17d4bf65d293175beb32d426cee Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 7 May 2018 20:00:03 +0800 Subject: [PATCH 46/80] Remove unused log --- .../vlayout/extend/ViewLifeCycleHelper.java | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java index ef2a904c..4c5bc5b2 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java @@ -33,22 +33,17 @@ public void checkViewStatusInScreen() { if (scrHeight == 0) { scrHeight = view.getContext().getResources().getDisplayMetrics().heightPixels; } -// Log.e("huang", "checkViewStatusInScreen: view=" + view.getTag(R.id.tag_layout_helper_bg) + " rect=" + rect.toString()); if (mVirtualLayoutManager.getVirtualLayoutDirection() == VirtualLayoutManager.LayoutState.LAYOUT_END) { - if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyDisAppear(view)) { -// Log.e("huang", "LAYOUT_END checkViewDisAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyDisAppearing(view)) { setViewDisappearing(view); - } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyAppear(view)) { -// Log.e("huang", "LAYOUT_END checkViewAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyAppearing(view)) { setViewAppearing(view); } } else { - if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyAppear(view)) { -// Log.e("huang", "LAYOUT_START checkViewAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyAppearing(view)) { setViewAppearing(view); - } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyDisAppear(view)) { -// Log.e("huang", "LAYOUT_START checkViewDisAppear: " + rect.toString() + "view=" + view.getTag(R.id.tag_layout_helper_bg)); + } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyDisAppearing(view)) { setViewDisappearing(view); } } @@ -56,30 +51,21 @@ public void checkViewStatusInScreen() { if (view.getTop() > 0 && view.getBottom() < scrHeight) { // fully in screen - if (isViewReadyAppear(view)) { - // if not appeared, call appear + if (isViewReadyAppearing(view)) { setViewAppearing(view); -// Log.e("huang", "Add appear: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); - } else { - if (getViewStatus(view) != STATUS.APPEARED) { - setViewAppeared(view); -// Log.e("huang", "Appeared: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); - } + } else if (isViewReadyAppeared(view)) { + setViewAppeared(view); } } else if (view.getBottom() < 0 || view.getTop() > scrHeight) { // not in screen - if (isViewReadyDisAppear(view)) { - // if not disappeared, call disappear + if (isViewReadyDisAppearing(view)) { setViewDisappearing(view); -// Log.e("huang", "Add disappear:" + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); - } else { - if (getViewStatus(view) != STATUS.DISAPPEARED) { - setViewDisappeared(view); -// Log.e("huang", "Disappeared: " + rect.toString() + " view=" + view.getTag(R.id.tag_layout_helper_bg)); - } + } else if (isViewReadyDisAppeared(view)) { + setViewDisappeared(view); } + } } } @@ -96,7 +82,7 @@ private void setViewstatus(View view, STATUS status) { mViewStatusMap.put(view, status); } - private boolean isViewReadyAppear(View view) { + private boolean isViewReadyAppearing(View view) { return getViewStatus(view) == STATUS.DISAPPEARED; } @@ -111,6 +97,10 @@ private void setViewAppearing(View view) { } } + private boolean isViewReadyAppeared(View view) { + return getViewStatus(view) == STATUS.APPEARING; + } + private void setViewAppeared(View view) { if (getViewStatus(view) == STATUS.APPEARED) { return; @@ -121,7 +111,7 @@ private void setViewAppeared(View view) { } } - private boolean isViewReadyDisAppear(View view) { + private boolean isViewReadyDisAppearing(View view) { return getViewStatus(view) == STATUS.APPEARED; } @@ -136,6 +126,10 @@ private void setViewDisappearing(View view) { } } + private boolean isViewReadyDisAppeared(View view) { + return getViewStatus(view) == STATUS.DISAPPEARING; + } + private void setViewDisappeared(View view) { if (getViewStatus(view) == STATUS.DISAPPEARED) { return; From ab5264fbf0db64508b236ee557f986993b1cd344 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 8 May 2018 10:44:18 +0800 Subject: [PATCH 47/80] Update demo --- .../vlayout/example/VLayoutActivity.java | 43 ++++++++++++++----- .../vlayout/ExposeLinearLayoutManagerEx.java | 2 +- .../android/vlayout/VirtualLayoutManager.java | 5 +++ .../vlayout/extend/ViewLifeCycleHelper.java | 12 +++--- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java index c6f49441..cc19dc5e 100644 --- a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java +++ b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java @@ -29,6 +29,7 @@ import com.alibaba.android.vlayout.RecyclablePagerAdapter; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; +import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; import com.alibaba.android.vlayout.layout.ColumnLayoutHelper; import com.alibaba.android.vlayout.layout.FixLayoutHelper; import com.alibaba.android.vlayout.layout.FloatLayoutHelper; @@ -109,8 +110,8 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); - mSwipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_container); -; + mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container); + ; mFirstText = (TextView) findViewById(R.id.first); mLastText = (TextView) findViewById(R.id.last); mCountText = (TextView) findViewById(R.id.count); @@ -135,8 +136,6 @@ public void onScrolled(RecyclerView recyclerView, int i, int i2) { } }); - layoutManager.setRecycleOffset(300); - recyclerView.setLayoutManager(layoutManager); // layoutManager.setReverseLayout(true); @@ -157,6 +156,31 @@ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, Recycle viewPool.setMaxRecycledViews(0, 20); + layoutManager.setRecycleOffset(300); + + // viewLifeCycleListener should be used with setRecycleOffset() + layoutManager.setViewLifeCycleListener(new ViewLifeCycleListener() { + @Override + public void onAppearing(View view) { +// Log.e("ViewLifeCycleTest", "onAppearing: " + view); + } + + @Override + public void onDisappearing(View view) { +// Log.e("ViewLifeCycleTest", "onDisappearing: " + view); + } + + @Override + public void onAppeared(View view) { +// Log.e("ViewLifeCycleTest", "onAppeared: " + view); + } + + @Override + public void onDisappeared(View view) { +// Log.e("ViewLifeCycleTest", "onDisappeared: " + view); + } + }); + final DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true); recyclerView.setAdapter(delegateAdapter); @@ -264,7 +288,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) { }); } - { + { RangeGridLayoutHelper layoutHelper = new RangeGridLayoutHelper(4); layoutHelper.setBgColor(Color.GREEN); layoutHelper.setWeights(new float[]{20f, 26.665f}); @@ -339,7 +363,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) { adapters.add(new SubAdapter(this, layoutHelper, 23)); } - + { SingleLayoutHelper layoutHelper = new SingleLayoutHelper(); layoutHelper.setBgColor(Color.BLUE); @@ -616,7 +640,7 @@ public void onBindViewHolder(MainViewHolder holder, int position) { } adapters.add( - new FooterAdapter(recyclerView, VLayoutActivity.this, new GridLayoutHelper(1), 1)); + new FooterAdapter(recyclerView, VLayoutActivity.this, new GridLayoutHelper(1), 1)); delegateAdapter.setAdapters(adapters); @@ -626,8 +650,8 @@ public void onBindViewHolder(MainViewHolder holder, int position) { trigger = new Runnable() { @Override public void run() { - //recyclerView.scrollToPosition(22); - //recyclerView.getAdapter().notifyDataSetChanged(); + //recyclerView.scrollToPosition(22); + //recyclerView.getAdapter().notifyDataSetChanged(); //mainHandler.postDelayed(trigger, 1000); //List newAdapters = new ArrayList<>(); //newAdapters.add((new SubAdapter(VLayoutActivity.this, new ColumnLayoutHelper(), 3))); @@ -658,7 +682,6 @@ public void onClick(View v) { }); - mainHandler.postDelayed(trigger, 1000); mSwipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java index 9e36a0f7..b569c353 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/ExposeLinearLayoutManagerEx.java @@ -129,7 +129,7 @@ class ExposeLinearLayoutManagerEx extends LinearLayoutManager { private final Method mEnsureLayoutStateMethod; - private int recycleOffset; + protected int recycleOffset; /** * Creates a vertical LinearLayoutManager diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 075dd827..355cf969 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -621,6 +621,11 @@ public void setViewLifeCycleListener(@NonNull ViewLifeCycleListener viewLifeCycl if (null == viewLifeCycleListener) { throw new IllegalArgumentException("ViewLifeCycleListener should not be null!"); } + + if (recycleOffset == 0) { + throw new IllegalArgumentException("ViewLifeCycleListener should work with virtualLayoutManager.setRecycleOffset()!"); + } + mViewLifeCycleHelper = new ViewLifeCycleHelper(this, viewLifeCycleListener); } diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java index 4c5bc5b2..6a248d42 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java @@ -35,20 +35,20 @@ public void checkViewStatusInScreen() { } if (mVirtualLayoutManager.getVirtualLayoutDirection() == VirtualLayoutManager.LayoutState.LAYOUT_END) { - if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyDisAppearing(view)) { + if (view.getTop() <= 0 && view.getBottom() >= 0 && isViewReadyDisAppearing(view)) { setViewDisappearing(view); - } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyAppearing(view)) { + } else if (view.getTop() <= scrHeight && view.getBottom() >= scrHeight && isViewReadyAppearing(view)) { setViewAppearing(view); } } else { - if (view.getTop() < 0 && view.getBottom() > 0 && isViewReadyAppearing(view)) { + if (view.getTop() <= 0 && view.getBottom() >= 0 && isViewReadyAppearing(view)) { setViewAppearing(view); - } else if (view.getTop() < scrHeight && view.getBottom() > scrHeight && isViewReadyDisAppearing(view)) { + } else if (view.getTop() <= scrHeight && view.getBottom() >= scrHeight && isViewReadyDisAppearing(view)) { setViewDisappearing(view); } } - if (view.getTop() > 0 && view.getBottom() < scrHeight) { + if (view.getTop() >= 0 && view.getBottom() <= scrHeight) { // fully in screen if (isViewReadyAppearing(view)) { @@ -57,7 +57,7 @@ public void checkViewStatusInScreen() { } else if (isViewReadyAppeared(view)) { setViewAppeared(view); } - } else if (view.getBottom() < 0 || view.getTop() > scrHeight) { + } else if (view.getBottom() <= 0 || view.getTop() >= scrHeight) { // not in screen if (isViewReadyDisAppearing(view)) { setViewDisappearing(view); From 1f6f8c8049a78bc101222f625711ad174b52c059 Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 16 May 2018 19:48:50 +0800 Subject: [PATCH 48/80] add performance monitor api --- .../vlayout/example/VLayoutActivity.java | 16 ++++++ .../android/vlayout/VirtualLayoutManager.java | 31 +++++++++++ .../vlayout/extend/PerformanceMonitor.java | 52 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java diff --git a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java index c6f49441..d17b5522 100644 --- a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java +++ b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java @@ -29,6 +29,7 @@ import com.alibaba.android.vlayout.RecyclablePagerAdapter; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; +import com.alibaba.android.vlayout.extend.PerformanceMonitor; import com.alibaba.android.vlayout.layout.ColumnLayoutHelper; import com.alibaba.android.vlayout.layout.FixLayoutHelper; import com.alibaba.android.vlayout.layout.FloatLayoutHelper; @@ -119,7 +120,22 @@ protected void onCreate(Bundle savedInstanceState) { final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_view); final VirtualLayoutManager layoutManager = new VirtualLayoutManager(this); + layoutManager.setPerformanceMonitor(new PerformanceMonitor() { + long start; + long end; + + @Override + public void recordStart(String phase, View view) { + start = System.currentTimeMillis(); + } + + @Override + public void recordEnd(String phase, View view) { + end = System.currentTimeMillis(); + Log.d("VLayoutActivity", view.getClass().getName() + " " + (end - start)); + } + }); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int scrollState) { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index fa29833b..93c266c4 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; +import com.alibaba.android.vlayout.extend.PerformanceMonitor; import com.alibaba.android.vlayout.layout.BaseLayoutHelper; import com.alibaba.android.vlayout.layout.DefaultLayoutHelper; import com.alibaba.android.vlayout.layout.FixAreaAdjuster; @@ -67,6 +68,8 @@ public class VirtualLayoutManager extends ExposeLinearLayoutManagerEx implements LayoutManagerHelper { protected static final String TAG = "VirtualLayoutManager"; + private static final String PHASE_MEASURE = "measure"; + private static final String PHASE_LAYOUT = "layout"; private static final String TRACE_LAYOUT = "VLM onLayoutChildren"; private static final String TRACE_SCROLL = "VLM scroll"; @@ -94,6 +97,7 @@ public static void enableDebugging(boolean isDebug) { private int mMaxMeasureSize = -1; + private PerformanceMonitor mPerformanceMonitor; public VirtualLayoutManager(@NonNull final Context context) { this(context, VERTICAL); @@ -121,6 +125,9 @@ public VirtualLayoutManager(@NonNull final Context context, int orientation, boo setHelperFinder(new RangeLayoutHelperFinder()); } + public void setPerformanceMonitor(PerformanceMonitor performanceMonitor) { + mPerformanceMonitor = performanceMonitor; + } public void setNoScrolling(boolean noScrolling) { this.mNoScrolling = noScrolling; @@ -1265,14 +1272,26 @@ public boolean canScrollVertically() { @Override public void layoutChildWithMargins(View child, int left, int top, int right, int bottom) { final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) child.getLayoutParams(); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordStart(PHASE_LAYOUT, child); + } layoutDecorated(child, left + lp.leftMargin, top + lp.topMargin, right - lp.rightMargin, bottom - lp.bottomMargin); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordEnd(PHASE_LAYOUT, child); + } } @Override public void layoutChild(View child, int left, int top, int right, int bottom) { + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordStart(PHASE_LAYOUT, child); + } layoutDecorated(child, left, top, right, bottom); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordEnd(PHASE_LAYOUT, child); + } } @Override @@ -1390,7 +1409,13 @@ private void measureChildWithDecorations(View child, int widthSpec, int heightSp calculateItemDecorationsForChild(child, mDecorInsets); widthSpec = updateSpecWithExtra(widthSpec, mDecorInsets.left, mDecorInsets.right); heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top, mDecorInsets.bottom); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordStart(PHASE_MEASURE, child); + } child.measure(widthSpec, heightSpec); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordEnd(PHASE_MEASURE, child); + } } private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec) { @@ -1405,7 +1430,13 @@ private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec = updateSpecWithExtra(heightSpec, mDecorInsets.top, mDecorInsets.bottom); } + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordStart(PHASE_MEASURE, child); + } child.measure(widthSpec, heightSpec); + if (mPerformanceMonitor != null) { + mPerformanceMonitor.recordEnd(PHASE_MEASURE, child); + } } /** diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java new file mode 100644 index 00000000..b28c0e06 --- /dev/null +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java @@ -0,0 +1,52 @@ +package com.alibaba.android.vlayout.extend; + +import android.view.View; + +/** + * Add callback during measure and layout, help you to monitor your view's performance.
+ * Designed as Class instead of Interface is able to extend api in future.
+ * + * Created by longerian on 2018/5/16. + * + * @author longerian + * @date 2018/05/16 + */ +public class PerformanceMonitor { + + /** + * Record the start time + * @param phase + * @param viewType + */ + public void recordStart(String phase, String viewType) { + + } + + /** + * Record the end time + * @param phase + * @param viewType + */ + public void recordEnd(String phase, String viewType) { + + } + + /** + * Record the start time + * @param phase + * @param view + */ + public void recordStart(String phase, View view) { + + } + + /** + * Record the end time + * @param phase + * @param view + */ + public void recordEnd(String phase, View view) { + + } + +} From 1677d73175dc5b73a2ccee4d5cf6b753f11b308b Mon Sep 17 00:00:00 2001 From: longerian Date: Wed, 16 May 2018 19:49:36 +0800 Subject: [PATCH 49/80] update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 021f2cc5..7c3adaae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.13 +VERSION_NAME=1.2.14 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From dd6446f33dc685181b122d63c8d9891f68a4dd4b Mon Sep 17 00:00:00 2001 From: longerian Date: Thu, 17 May 2018 18:55:12 +0800 Subject: [PATCH 50/80] update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7c3adaae..3b396667 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.14 +VERSION_NAME=1.3.0 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From 75b4c7c02bb95d05744744f2b82d76e6254c3d91 Mon Sep 17 00:00:00 2001 From: longerian Date: Thu, 17 May 2018 19:01:52 +0800 Subject: [PATCH 51/80] Revert "update version" This reverts commit dd6446f33dc685181b122d63c8d9891f68a4dd4b. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 3b396667..7c3adaae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.3.0 +VERSION_NAME=1.2.14 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From 07304ddfc689a7459f0e037ac756aa9d77f48c9b Mon Sep 17 00:00:00 2001 From: longerian Date: Tue, 22 May 2018 13:13:58 +0800 Subject: [PATCH 52/80] add keep for api --- gradle.properties | 2 +- .../alibaba/android/vlayout/extend/PerformanceMonitor.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7c3adaae..2b1f3026 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.14 +VERSION_NAME=1.2.15 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java index b28c0e06..7c4ec661 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/PerformanceMonitor.java @@ -1,5 +1,6 @@ package com.alibaba.android.vlayout.extend; +import android.support.annotation.Keep; import android.view.View; /** @@ -18,6 +19,7 @@ public class PerformanceMonitor { * @param phase * @param viewType */ + @Keep public void recordStart(String phase, String viewType) { } @@ -27,6 +29,7 @@ public void recordStart(String phase, String viewType) { * @param phase * @param viewType */ + @Keep public void recordEnd(String phase, String viewType) { } @@ -36,6 +39,7 @@ public void recordEnd(String phase, String viewType) { * @param phase * @param view */ + @Keep public void recordStart(String phase, View view) { } @@ -45,6 +49,7 @@ public void recordStart(String phase, View view) { * @param phase * @param view */ + @Keep public void recordEnd(String phase, View view) { } From ba9a68198e65c753a4bc0af1cb5496efd76dbb0a Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 21 Jun 2018 10:05:33 +0800 Subject: [PATCH 53/80] Add interface to control can scroll feature. --- .../android/vlayout/VirtualLayoutManager.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 93c266c4..9e1cf60a 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -93,6 +93,10 @@ public static void enableDebugging(boolean isDebug) { private boolean mNestedScrolling = false; + private boolean mCanScrollHorizontally; + + private boolean mCanScrollVertically; + private boolean mEnableMarginOverlapping = false; private int mMaxMeasureSize = -1; @@ -122,6 +126,8 @@ public VirtualLayoutManager(@NonNull final Context context, int orientation, boo super(context, orientation, reverseLayout); this.mOrientationHelper = OrientationHelperEx.createOrientationHelper(this, orientation); this.mSecondaryOrientationHelper = OrientationHelperEx.createOrientationHelper(this, orientation == VERTICAL ? HORIZONTAL : VERTICAL); + this.mCanScrollVertically = super.canScrollVertically(); + this.mCanScrollHorizontally = super.canScrollHorizontally(); setHelperFinder(new RangeLayoutHelperFinder()); } @@ -136,6 +142,14 @@ public void setNoScrolling(boolean noScrolling) { mSpaceMeasuring = false; } + public void setCanScrollVertically(boolean canScrollVertically) { + this.mCanScrollVertically = canScrollVertically; + } + + public void setCanScrollHorizontally(boolean canScrollHorizontally) { + this.mCanScrollHorizontally = canScrollHorizontally; + } + public void setNestedScrolling(boolean nestedScrolling) { setNestedScrolling(nestedScrolling, -1); } @@ -1261,12 +1275,12 @@ public int getChildMeasureSpec(int parentSize, int size, boolean canScroll) { @Override public boolean canScrollHorizontally() { - return super.canScrollHorizontally() && !mNoScrolling; + return mCanScrollHorizontally && !mNoScrolling; } @Override public boolean canScrollVertically() { - return super.canScrollVertically() && !mNoScrolling; + return mCanScrollVertically && !mNoScrolling; } @Override From 42bc30af3aec4b4121b718364e8efcfbefe87613 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 21 Jun 2018 10:14:58 +0800 Subject: [PATCH 54/80] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2b1f3026..242d0a21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.15 +VERSION_NAME=1.2.16 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From d6762ac00d4a57df852520529a94ad36925a18ef Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 26 Jul 2018 16:24:45 +0800 Subject: [PATCH 55/80] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 772b8b01..76b41b7f 100644 --- a/README.md +++ b/README.md @@ -168,9 +168,3 @@ Before you open an issue or create a pull request, please read [Contributing Gui # LICENSE Vlayout is available under the MIT license. - -# WeChatGroup - -![](https://img.alicdn.com/tfs/TB11_2_kbSYBuNjSspiXXXNzpXa-167-167.png) - -Search `tangram_` or scan the QR code above to be invited in WeChat. From 8ec24f12e8d896fb56ac921efe7ff37f4d29cd4b Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 26 Jul 2018 16:25:36 +0800 Subject: [PATCH 56/80] Update README-ch.md --- README-ch.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README-ch.md b/README-ch.md index c34404b0..0425c1f2 100644 --- a/README-ch.md +++ b/README-ch.md @@ -169,9 +169,3 @@ recycler.setAdapter(myAdapter); # 开源许可证 vlayout遵循MIT开源许可证协议。 - -# 微信群 - -![](https://img.alicdn.com/tfs/TB11_2_kbSYBuNjSspiXXXNzpXa-167-167.png) - -搜索 `tangram_` 或者扫描以上二维码添加 Tangram 为好友,以便我们邀请你入群。 From a3da84d0faee49558338f2d4216de8b651315021 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 30 Jul 2018 15:14:13 +0800 Subject: [PATCH 57/80] Fix reverse cantor not correct. Fix #358, Fix #344 --- .../src/main/java/com/alibaba/android/vlayout/Cantor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/Cantor.java b/vlayout/src/main/java/com/alibaba/android/vlayout/Cantor.java index 73b2d7e8..1729b0b4 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/Cantor.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/Cantor.java @@ -28,11 +28,11 @@ public static void reverseCantor(long cantor, long[] result) { result = new long[2]; } // reverse Cantor Function - int w = (int) (Math.floor(Math.sqrt(8 * cantor + 1) - 1) / 2); - int t = (w * w + w) / 2; + long w = (long) (Math.floor(Math.sqrt(8 * cantor + 1) - 1) / 2); + long t = (w * w + w) / 2; - int k2 = (int)(cantor - t); - int k1 = w - k2; + long k2 = cantor - t; + long k1 = w - k2; result[0] = k1; result[1] = k2; } From 7e08f2e659a64b347a1369314ef81e6adcec2cd5 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 31 Jul 2018 15:21:26 +0800 Subject: [PATCH 58/80] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 242d0a21..994ff7ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.16 +VERSION_NAME=1.2.17 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From dd743167e697aece8f181183bee37e12805b04b6 Mon Sep 17 00:00:00 2001 From: budao Date: Wed, 23 Jan 2019 12:11:55 +0800 Subject: [PATCH 59/80] =?UTF-8?q?=E5=85=B3=E9=94=AE=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E4=B8=8BLayoutHelpers=E7=9B=B8=E5=85=B3=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.LinkedList的高效遍历,复杂度降低一个数量级,在2000+元素个数下无卡顿 2.排序过程简化,复用中间数组 3.二分搜索避免LinkedList的get频繁调用,复用数组根据索引直接定位 --- .../vlayout/RangeLayoutHelperFinder.java | 27 ++-- .../android/vlayout/VirtualLayoutManager.java | 115 +++++++++++------- 2 files changed, 89 insertions(+), 53 deletions(-) diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java index cde8451e..3201b7f1 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/RangeLayoutHelperFinder.java @@ -27,10 +27,13 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; /** * An implement of {@link LayoutHelperFinder} which finds layoutHelpers by position @@ -46,6 +49,8 @@ public class RangeLayoutHelperFinder extends LayoutHelperFinder { @NonNull private List mReverseLayoutHelpers =new LinkedList<>(); + private LayoutHelperItem[] mSortedLayoutHelpers = null; + @NonNull private Comparator mLayoutHelperItemComparator = new Comparator() { @Override @@ -68,16 +73,21 @@ public void setLayouts(@Nullable List layouts) { mReverseLayoutHelpers.clear(); mLayoutHelperItems.clear(); if (layouts != null) { - for (int i = 0, size = layouts.size(); i < size; i++) { - LayoutHelper helper = layouts.get(i); + ListIterator iterator = layouts.listIterator(); + LayoutHelper helper = null; + while (iterator.hasNext()) { + helper = iterator.next(); mLayoutHelpers.add(helper); mLayoutHelperItems.add(new LayoutHelperItem(helper)); } - for (int i = layouts.size() - 1; i >= 0; i--) { - mReverseLayoutHelpers.add(layouts.get(i)); + + while (iterator.hasPrevious()) { + mReverseLayoutHelpers.add(iterator.previous()); } - Collections.sort(mLayoutHelperItems, mLayoutHelperItemComparator); + // Collections.sort(mLayoutHelperItems, mLayoutHelperItemComparator); + mSortedLayoutHelpers = mLayoutHelperItems.toArray(new LayoutHelperItem[mLayoutHelperItems.size()]); + Arrays.sort(mSortedLayoutHelpers, mLayoutHelperItemComparator); } } @@ -90,18 +100,17 @@ protected List getLayoutHelpers() { @Nullable @Override public LayoutHelper getLayoutHelper(int position) { - final int count = mLayoutHelperItems.size(); - if (count == 0) { + if (mSortedLayoutHelpers == null || mSortedLayoutHelpers.length == 0) { return null; } + final int count = mSortedLayoutHelpers.length; int s = 0, e = count - 1, m; LayoutHelperItem rs = null; - // binary search range while (s <= e) { m = (s + e) / 2; - rs = mLayoutHelperItems.get(m); + rs = mSortedLayoutHelpers[m]; if (rs.getStartPosition() > position) { e = m - 1; } else if (rs.getEndPosition() < position) { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 13a9c96d..7653b3e7 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -47,12 +47,14 @@ import android.view.ViewGroup; import android.view.ViewParent; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; @@ -107,6 +109,20 @@ public static void enableDebugging(boolean isDebug) { private ViewLifeCycleHelper mViewLifeCycleHelper; + private Comparator, Integer>> mRangeComparator = new Comparator, Integer>>() { + @Override + public int compare(Pair, Integer> a, Pair, Integer> b) { + if (a == null && b == null) return 0; + if (a == null) return -1; + if (b == null) return 1; + + Range lr = a.first; + Range rr = b.first; + + return lr.getLower() - rr.getLower(); + } + }; + public VirtualLayoutManager(@NonNull final Context context) { this(context, VERTICAL); } @@ -175,9 +191,12 @@ public void setHelperFinder(@NonNull final LayoutHelperFinder finder) { List helpers = new LinkedList<>(); if (this.mHelperFinder != null) { List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper helper = layoutHelpers.get(i); - helpers.add(helper); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); + helpers.add(layoutHelper); + } } @@ -211,17 +230,18 @@ public void setFixOffset(int left, int top, int right, int bottom) { */ public void setLayoutHelpers(@Nullable List helpers) { List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper helper = layoutHelpers.get(i); + Iterator it0 = layoutHelpers.iterator(); + while (it0.hasNext()) { + LayoutHelper helper = it0.next(); oldHelpersSet.put(System.identityHashCode(helper), helper); } // set ranges if (helpers != null) { int start = 0; - for (int i = 0; i < helpers.size(); i++) { - LayoutHelper helper = helpers.get(i); - + Iterator it1 = helpers.iterator(); + while (it1.hasNext()) { + LayoutHelper helper = it1.next(); if (helper instanceof FixAreaLayoutHelper) { ((FixAreaLayoutHelper) helper).setAdjuster(mFixAreaAdjustor); } @@ -244,12 +264,12 @@ public void setLayoutHelpers(@Nullable List helpers) { this.mHelperFinder.setLayouts(helpers); layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper helper = layoutHelpers.get(i); - newHelpersSet.put(System.identityHashCode(helper), helper); + Iterator iterator = layoutHelpers.iterator(); + while (iterator.hasNext()) { + LayoutHelper layoutHelper = iterator.next(); + newHelpersSet.put(System.identityHashCode(layoutHelper), layoutHelper); } - for (Iterator> it = oldHelpersSet.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); Integer key = entry.getKey(); @@ -364,8 +384,10 @@ public void onAnchorReady(RecyclerView.State state, ExposeLinearLayoutManagerEx. mTempAnchorInfoWrapper.position = anchorInfo.mPosition; mTempAnchorInfoWrapper.coordinate = anchorInfo.mCoordinate; List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.onRefreshLayout(state, mTempAnchorInfoWrapper, this); } } @@ -434,8 +456,10 @@ private void runPreLayout(RecyclerView.Recycler recycler, RecyclerView.State sta if (mNested == 0) { List reverseLayoutHelpers = mHelperFinder.reverse(); - for (int i = 0, size = reverseLayoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = reverseLayoutHelpers.get(i); + Iterator iterator = reverseLayoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.beforeLayout(recycler, state, this); } } @@ -450,8 +474,10 @@ private void runPostLayout(RecyclerView.Recycler recycler, RecyclerView.State st final int startPosition = findFirstVisibleItemPosition(); final int endPosition = findLastVisibleItemPosition(); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); try { layoutHelper.afterLayout(recycler, state, startPosition, endPosition, scrolled, this); } catch (Exception e) { @@ -608,8 +634,10 @@ public void onScrollStateChanged(int state) { int startPosition = findFirstVisibleItemPosition(); int endPosition = findLastVisibleItemPosition(); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.onScrollStateChanged(state, startPosition, endPosition, this); } } @@ -619,9 +647,12 @@ public void offsetChildrenHorizontal(int dx) { super.offsetChildrenHorizontal(dx); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.onOffsetChildrenHorizontal(dx, this); + } } @@ -629,8 +660,10 @@ public void offsetChildrenHorizontal(int dx) { public void offsetChildrenVertical(int dy) { super.offsetChildrenVertical(dy); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.onOffsetChildrenVertical(dy, this); } @@ -657,7 +690,7 @@ public int getVirtualLayoutDirection() { private LayoutStateWrapper mTempLayoutStateWrapper = new LayoutStateWrapper(); - private List, Integer>> mRangeLengths = new LinkedList<>(); + private List, Integer>> mRangeLengths = new ArrayList<>(); @Nullable private int findRangeLength(@NonNull final Range range) { @@ -732,19 +765,7 @@ protected void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State st } mRangeLengths.add(Pair.create(range, consumed)); - Collections.sort(mRangeLengths, new Comparator, Integer>>() { - @Override - public int compare(Pair, Integer> a, Pair, Integer> b) { - if (a == null && b == null) return 0; - if (a == null) return -1; - if (b == null) return 1; - - Range lr = a.first; - Range rr = b.first; - - return lr.getLower() - rr.getLower(); - } - }); + Collections.sort(mRangeLengths, mRangeComparator); } } @@ -852,8 +873,10 @@ public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCo @Override public void onItemsChanged(RecyclerView recyclerView) { List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.onItemsChanged(this); } @@ -907,8 +930,10 @@ public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycl super.onDetachedFromWindow(view, recycler); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); layoutHelper.clear(this); } @@ -1141,8 +1166,10 @@ public List getFixedViews() { // TODO: support zIndex? List views = new LinkedList<>(); List layoutHelpers = mHelperFinder.getLayoutHelpers(); - for (int i = 0, size = layoutHelpers.size(); i < size; i++) { - LayoutHelper layoutHelper = layoutHelpers.get(i); + Iterator iterator = layoutHelpers.iterator(); + LayoutHelper layoutHelper = null; + while (iterator.hasNext()) { + layoutHelper = iterator.next(); View fixedView = layoutHelper.getFixedView(); if (fixedView != null) { views.add(fixedView); From c53f13b3f834e189ccc8ccb1662ab56891c25257 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 25 Feb 2019 18:30:08 +0800 Subject: [PATCH 60/80] Add listener for sticky status. --- gradle.properties | 2 +- .../android/vlayout/VirtualLayoutManager.java | 23 ++++---- .../vlayout/layout/StickyLayoutHelper.java | 54 ++++++++++++++----- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/gradle.properties b/gradle.properties index 994ff7ac..554fc322 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.17 +VERSION_NAME=1.2.20 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 7653b3e7..6e23c2b9 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -24,14 +24,6 @@ package com.alibaba.android.vlayout; -import com.alibaba.android.vlayout.extend.PerformanceMonitor; -import com.alibaba.android.vlayout.extend.ViewLifeCycleHelper; -import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; -import com.alibaba.android.vlayout.layout.BaseLayoutHelper; -import com.alibaba.android.vlayout.layout.DefaultLayoutHelper; -import com.alibaba.android.vlayout.layout.FixAreaAdjuster; -import com.alibaba.android.vlayout.layout.FixAreaLayoutHelper; - import android.content.Context; import android.graphics.Rect; import android.os.Build; @@ -47,6 +39,14 @@ import android.view.ViewGroup; import android.view.ViewParent; +import com.alibaba.android.vlayout.extend.PerformanceMonitor; +import com.alibaba.android.vlayout.extend.ViewLifeCycleHelper; +import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; +import com.alibaba.android.vlayout.layout.BaseLayoutHelper; +import com.alibaba.android.vlayout.layout.DefaultLayoutHelper; +import com.alibaba.android.vlayout.layout.FixAreaAdjuster; +import com.alibaba.android.vlayout.layout.FixAreaLayoutHelper; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -54,7 +54,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; import java.util.Map; @@ -77,7 +76,7 @@ public class VirtualLayoutManager extends ExposeLinearLayoutManagerEx implements private static final String TRACE_LAYOUT = "VLM onLayoutChildren"; private static final String TRACE_SCROLL = "VLM scroll"; - private static boolean sDebuggable = false; + public static boolean sDebuggable = false; public static void enableDebugging(boolean isDebug) { sDebuggable = isDebug; @@ -744,7 +743,9 @@ protected void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State st // no item consumed if (layoutState.mCurrentPosition == position) { - Log.w(TAG, "layoutHelper[" + layoutHelper.getClass().getSimpleName() + "@" + layoutHelper.toString() + "] consumes no item!"); + if (sDebuggable) { + Log.w(TAG, "layoutHelper[" + layoutHelper.getClass().getSimpleName() + "@" + layoutHelper.toString() + "] consumes no item!"); + } // break as no item consumed result.mFinished = true; } else { diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index cc35fecb..39c11db7 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -24,17 +24,17 @@ package com.alibaba.android.vlayout.layout; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; + import com.alibaba.android.vlayout.LayoutHelper; import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.View; - import static android.support.v7.widget.LinearLayoutManager.VERTICAL; @@ -45,18 +45,27 @@ * @since 1.0.0 */ public class StickyLayoutHelper extends FixAreaLayoutHelper { + public interface StickyListener { + void onSticky(int pos, View view); + + void onUnSticky(int pos, View view); + } private static final String TAG = "StickyStartLayoutHelper"; private int mPos = -1; private boolean mStickyStart = true; - private int mOffset = 0; + private int mOffset = 0; private View mFixView = null; + private boolean mDoNormalHandle = false; + private boolean isLastStatusSticking = true; + + private StickyListener stickyListener; public StickyLayoutHelper() { this(true); @@ -173,7 +182,9 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state top = orientationHelper.getStartAfterPadding() + mMarginTop + mOffset + mAdjuster.top; bottom = top + result.mConsumed; } else { - Log.i("Sticky", "remainingSpace: " + remainingSpace + " offset: " + mOffset); + if (VirtualLayoutManager.sDebuggable) { + Log.i("Sticky", "remainingSpace: " + remainingSpace + " offset: " + mOffset); + } } } @@ -223,8 +234,6 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } else { // result.mConsumed += mOffset; } - - } @@ -292,15 +301,28 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state fixLayoutStateInCase2(orientationHelper, recycler, startPosition, endPosition, helper); } - if (mFixView != null){ + if (mFixView != null) { mFixView.setBackgroundColor(mBgColor); } + + if (stickyListener != null) { + if (isLastStatusSticking && !isStickyNow()) { + stickyListener.onUnSticky(mPos, mFixView); + isLastStatusSticking = false; + } else if (!isLastStatusSticking && isStickyNow()) { + stickyListener.onSticky(mPos, mFixView); + isLastStatusSticking = true; + } + } } private void fixLayoutStateFromAbnormal2Normal(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, - LayoutManagerHelper helper) { + LayoutManagerHelper helper) { //fix status, from abnormal to normal - Log.i(TAG, "abnormal pos: " + mPos + " start: " + startPosition + " end: " + endPosition); + if (VirtualLayoutManager.sDebuggable) { + Log.i(TAG, "abnormal pos: " + mPos + " start: " + startPosition + " end: " + endPosition); + } + if (mFixView != null) { int top, bottom; View refer = null; @@ -348,7 +370,7 @@ private void fixLayoutStateFromAbnormal2Normal(OrientationHelperEx orientationHe } private void fixLayoutStateInCase1(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, - LayoutManagerHelper helper) { + LayoutManagerHelper helper) { // considering the case when last layoutHelper has margin bottom // 1. normal flow to abnormal flow; 2. abnormal flow to normal flow if ((mStickyStart && endPosition >= mPos) || (!mStickyStart && startPosition <= mPos)) { @@ -491,7 +513,7 @@ private void fixLayoutStateInCase1(OrientationHelperEx orientationHelper, Recycl } private void fixLayoutStateInCase2(OrientationHelperEx orientationHelper, RecyclerView.Recycler recycler, int startPosition, int endPosition, - LayoutManagerHelper helper) { + LayoutManagerHelper helper) { // 1. normal flow to abnormal flow; 2. abnormal flow to normal flow // (mDoNormalHandle && mFixView != null) || (!mDoNormalHandle && mFixView == null) View eView = mFixView; @@ -728,5 +750,9 @@ private void doMeasure(View view, LayoutManagerHelper helper) { } } + + public void setStickyListener(StickyListener stickyListener) { + this.stickyListener = stickyListener; + } } From 0c03bbc5fb1643bf66ee2c90d2e9277a34074a0d Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 5 Mar 2019 15:20:06 +0800 Subject: [PATCH 61/80] Update version. --- gradle.properties | 2 +- .../com/alibaba/android/vlayout/VirtualLayoutManager.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 554fc322..344d4031 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.20 +VERSION_NAME=1.2.21 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 6e23c2b9..96db6593 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -676,10 +676,6 @@ public void setViewLifeCycleListener(@NonNull ViewLifeCycleListener viewLifeCycl throw new IllegalArgumentException("ViewLifeCycleListener should not be null!"); } - if (recycleOffset == 0) { - throw new IllegalArgumentException("ViewLifeCycleListener should work with virtualLayoutManager.setRecycleOffset()!"); - } - mViewLifeCycleHelper = new ViewLifeCycleHelper(this, viewLifeCycleListener); } From 6c5232cbc1e0c9489e347b29603105d730f5accb Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 12 Mar 2019 19:23:02 +0800 Subject: [PATCH 62/80] Add can scroll listener. --- .../vlayout/example/VLayoutActivity.java | 15 +++++++++++++++ .../android/vlayout/VirtualLayoutManager.java | 19 +++++++++++++++++-- .../LayoutManagerCanScrollListener.java | 7 +++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 vlayout/src/main/java/com/alibaba/android/vlayout/extend/LayoutManagerCanScrollListener.java diff --git a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java index 318f3195..dca43f00 100644 --- a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java +++ b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java @@ -29,6 +29,7 @@ import com.alibaba.android.vlayout.RecyclablePagerAdapter; import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutParams; +import com.alibaba.android.vlayout.extend.LayoutManagerCanScrollListener; import com.alibaba.android.vlayout.extend.PerformanceMonitor; import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; import com.alibaba.android.vlayout.layout.ColumnLayoutHelper; @@ -197,6 +198,20 @@ public void onDisappeared(View view) { } }); + layoutManager.setLayoutManagerCanScrollListener(new LayoutManagerCanScrollListener() { + @Override + public boolean canScrollVertically() { + Log.i("vlayout", "canScrollVertically: "); + return true; + } + + @Override + public boolean canScrollHorizontally() { + Log.i("vlayout", "canScrollHorizontally: "); + return true; + } + }); + final DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true); recyclerView.setAdapter(delegateAdapter); diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java index 96db6593..257d960c 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/VirtualLayoutManager.java @@ -39,6 +39,7 @@ import android.view.ViewGroup; import android.view.ViewParent; +import com.alibaba.android.vlayout.extend.LayoutManagerCanScrollListener; import com.alibaba.android.vlayout.extend.PerformanceMonitor; import com.alibaba.android.vlayout.extend.ViewLifeCycleHelper; import com.alibaba.android.vlayout.extend.ViewLifeCycleListener; @@ -100,6 +101,8 @@ public static void enableDebugging(boolean isDebug) { private boolean mCanScrollVertically; + private LayoutManagerCanScrollListener layoutManagerCanScrollListener; + private boolean mEnableMarginOverlapping = false; private int mMaxMeasureSize = -1; @@ -169,6 +172,10 @@ public void setCanScrollHorizontally(boolean canScrollHorizontally) { this.mCanScrollHorizontally = canScrollHorizontally; } + public void setLayoutManagerCanScrollListener(LayoutManagerCanScrollListener layoutManagerCanScrollListener) { + this.layoutManagerCanScrollListener = layoutManagerCanScrollListener; + } + public void setNestedScrolling(boolean nestedScrolling) { setNestedScrolling(nestedScrolling, -1); } @@ -1327,12 +1334,20 @@ public int getChildMeasureSpec(int parentSize, int size, boolean canScroll) { @Override public boolean canScrollHorizontally() { - return mCanScrollHorizontally && !mNoScrolling; + boolean ret = true; + if (layoutManagerCanScrollListener != null) { + ret = ret && layoutManagerCanScrollListener.canScrollHorizontally(); + } + return mCanScrollHorizontally && !mNoScrolling && ret; } @Override public boolean canScrollVertically() { - return mCanScrollVertically && !mNoScrolling; + boolean ret = true; + if (layoutManagerCanScrollListener != null) { + ret = ret && layoutManagerCanScrollListener.canScrollVertically(); + } + return mCanScrollVertically && !mNoScrolling && ret; } @Override diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/LayoutManagerCanScrollListener.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/LayoutManagerCanScrollListener.java new file mode 100644 index 00000000..01d3b011 --- /dev/null +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/LayoutManagerCanScrollListener.java @@ -0,0 +1,7 @@ +package com.alibaba.android.vlayout.extend; + +public interface LayoutManagerCanScrollListener { + boolean canScrollVertically(); + + boolean canScrollHorizontally(); +} From bbd2ba451361d1ebde6dca00d7e6ffa89bf6e1cf Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 12 Mar 2019 19:25:25 +0800 Subject: [PATCH 63/80] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 344d4031..3bd1b920 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.21 +VERSION_NAME=1.2.22 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=25 From 8a5a51d9d2eeb91fed2ee331a4cf3496282452ce Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 22 Apr 2019 19:18:23 +0800 Subject: [PATCH 64/80] FIx view lifecycle of sticky layout helper. --- gradle.properties | 8 ++++---- .../android/vlayout/layout/StickyLayoutHelper.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3bd1b920..8f74f7bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,9 +44,9 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.22 +VERSION_NAME=1.2.23 PACKAGING_TYPE=aar useNewSupportLibrary=true -systemProp.compileSdkVersion=25 -systemProp.targetSdkVersion=25 -systemProp.buildToolsVersion=25.0.3 +systemProp.compileSdkVersion=26 +systemProp.targetSdkVersion=26 +systemProp.buildToolsVersion=26.0.2 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index 39c11db7..f107f159 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -709,8 +709,8 @@ public View getFixedView() { public void onClear(LayoutManagerHelper helper) { super.onClear(helper); if (mFixView != null) { - helper.removeChildView(mFixView); helper.recycleView(mFixView); + helper.removeChildView(mFixView); mFixView = null; } } From 6213cebfe9141338c3cf79932b60c5cc8fb9d7a3 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Wed, 22 May 2019 11:38:42 +0800 Subject: [PATCH 65/80] Update default max scap size to 20, and provide interface to set it. --- gradle.properties | 2 +- .../android/vlayout/extend/InnerRecycledViewPool.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8f74f7bb..9aa3ca4a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.23 +VERSION_NAME=1.2.24 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/InnerRecycledViewPool.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/InnerRecycledViewPool.java index 1c9e5081..b51981e5 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/InnerRecycledViewPool.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/InnerRecycledViewPool.java @@ -30,9 +30,6 @@ import android.view.View; import java.io.Closeable; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; /** * Wrapping original RecycledViewPool to provides destroy callback on Views @@ -44,7 +41,7 @@ public final class InnerRecycledViewPool extends RecyclerView.RecycledViewPool { private static final String TAG = "InnerRecycledViewPool"; - private static final int DEFAULT_MAX_SIZE = 5; + private static int DEFAULT_MAX_SIZE = 20; /* * Wrapped InnerPool @@ -177,4 +174,8 @@ private void destroyViewHolder(RecyclerView.ViewHolder holder) { } } } + + public void setDefaultMaxSize(int maxSize) { + DEFAULT_MAX_SIZE = maxSize; + } } From a3c36fe13b588d8a9c8f574d650a9a30c7491864 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 15 Jul 2019 11:56:50 +0800 Subject: [PATCH 66/80] Fix sticky listener not correct --- gradle.properties | 2 +- .../android/vlayout/layout/StickyLayoutHelper.java | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9aa3ca4a..61bd5de0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.24 +VERSION_NAME=1.2.25 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index f107f159..1780d4a9 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -498,7 +498,9 @@ private void fixLayoutStateInCase1(OrientationHelperEx orientationHelper, Recycl if (mDoNormalHandle) { // offset if (index >= 0) { - helper.addChildView(mFixView, index); + if (mFixView.getParent() == null) { + helper.addChildView(mFixView, index); + } mFixView = null; } } else { @@ -530,7 +532,7 @@ private void fixLayoutStateInCase2(OrientationHelperEx orientationHelper, Recycl if (eView == null) { // TODO? why do condition here? - if (mOffset + (mStickyStart ? startAdjust : endAdjust) > 0) { + if (mOffset + (mStickyStart ? startAdjust : endAdjust) >= 0) { normalHandle = true; } mFixView = recycler.getViewForPosition(mPos); @@ -687,7 +689,9 @@ private void fixLayoutStateInCase2(OrientationHelperEx orientationHelper, Recycl if (normalHandle) { // offset if (index >= 0) { - helper.addChildView(mFixView, index); + if (mFixView.getParent() == null) { + helper.addChildView(mFixView, index); + } mFixView = null; } } else { From 4cefde56e72167f2bb9d47c5d826f832f27feabb Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 16 Jul 2019 17:21:23 +0800 Subject: [PATCH 67/80] Fix layout error when use padding in RangeGridLayoutHelper. --- gradle.properties | 2 +- .../vlayout/layout/RangeGridLayoutHelper.java | 48 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gradle.properties b/gradle.properties index 61bd5de0..4c0bae3a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.25 +VERSION_NAME=1.2.26 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java index 9869032f..4cf267e1 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java @@ -24,7 +24,13 @@ package com.alibaba.android.vlayout.layout; -import java.util.Arrays; +import android.support.annotation.NonNull; +import android.support.v4.util.ArrayMap; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Recycler; +import android.support.v7.widget.RecyclerView.State; +import android.util.Log; +import android.view.View; import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; @@ -35,13 +41,7 @@ import com.alibaba.android.vlayout.layout.GridLayoutHelper.DefaultSpanSizeLookup; import com.alibaba.android.vlayout.layout.GridLayoutHelper.SpanSizeLookup; -import android.support.annotation.NonNull; -import android.support.v4.util.ArrayMap; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.RecyclerView.Recycler; -import android.support.v7.widget.RecyclerView.State; -import android.util.Log; -import android.view.View; +import java.util.Arrays; import static android.support.v7.widget.LinearLayoutManager.VERTICAL; @@ -258,8 +258,8 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (!layingOutInPrimaryDirection) { // fill the remaining spacing this row - int itemSpanIndex = getSpanIndex(rangeStyle.mSpanSizeLookup, rangeStyle.mSpanCount, recycler, state, layoutState.getCurrentPosition()); - int itemSpanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, layoutState.getCurrentPosition()); + int itemSpanIndex = getSpanIndex(rangeStyle.mSpanSizeLookup, rangeStyle.mSpanCount, recycler, state, currentPosition); + int itemSpanSize = getSpanSize(rangeStyle.mSpanSizeLookup, recycler, state, currentPosition); remainingSpan = itemSpanIndex + itemSpanSize; @@ -343,20 +343,12 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state break; // item did not fit into this row or column } - View view = layoutState.next(recycler); - if (view == null) { - break; - } - if (!isStartLine) { isStartLine = helper.getReverseLayout() ? pos == mRangeStyle.getRange().getUpper().intValue() : pos == mRangeStyle.getRange().getLower().intValue(); } if (!isSecondStartLine) { if (!rangeStyle.equals(mRangeStyle)) { - if (mLayoutWithAnchor) { - pos = layoutState.getCurrentPosition(); - } isSecondStartLine = helper.getReverseLayout() ? pos == rangeStyle.getRange().getUpper() .intValue() : pos == rangeStyle.getRange().getLower().intValue(); } @@ -369,14 +361,19 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (!isSecondEndLine) { if (!rangeStyle.equals(mRangeStyle)) { - if (mLayoutWithAnchor) { - pos = layoutState.getCurrentPosition(); - } isSecondEndLine = helper.getReverseLayout() ? pos == rangeStyle.getRange().getLower() .intValue() : pos == rangeStyle.getRange().getUpper().intValue(); + if (DEBUG) { + Log.d(TAG, "isSecondEndLineLogic:" + isSecondEndLine + " helper.getReverseLayout()=" + helper.getReverseLayout() + " pos=" + pos + " rangeStyle.getRange().getLower()=" + rangeStyle.getRange().getLower() + " rangeStyle.getRange().getUpper()=" + rangeStyle.getRange().getUpper()); + } } } + View view = layoutState.next(recycler); + if (view == null) { + break; + } + consumedSpanCount += spanSize; rangeStyle.mSet[count] = view; count++; @@ -528,6 +525,9 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (isSecondEndLine) { secondEndSpace = (layoutInVertical ? rangeStyle.getMarginBottom() + rangeStyle.getPaddingBottom() : rangeStyle.getMarginRight() + rangeStyle.getPaddingRight()); + if (DEBUG) { + Log.d(TAG, "isSecondEndLineLogic:" + isSecondEndLine + " pos=" + currentPosition + " secondEndSpace=" + secondEndSpace); + } } @@ -613,8 +613,8 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (DEBUG) { Log.d(TAG, - (layoutStart ? "⬆ " : "⬇ ") + currentPosition + " consumed " + result.mConsumed + " startSpace " + startSpace + " endSpace " - + endSpace + " secondStartSpace " + secondStartSpace + " secondEndSpace " + secondEndSpace + " lastUnconsumedSpace " + lastUnconsumedSpace); + (layoutStart ? "⬆ " : "⬇ ") + currentPosition + " consumed " + result.mConsumed + " startSpace " + startSpace + " endSpace " + + endSpace + " secondStartSpace " + secondStartSpace + " secondEndSpace " + secondEndSpace + " lastUnconsumedSpace " + lastUnconsumedSpace + " isSecondEndLine=" + isSecondEndLine); } int left = 0, right = 0, top = 0, bottom = 0; @@ -670,7 +670,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (DEBUG) { Log.d(TAG, "layout item in position: " + params.getViewPosition() + " with text with SpanIndex: " + index + " into (" + - left + ", " + top + ", " + right + ", " + bottom + " )"); + left + ", " + top + ", " + right + ", " + bottom + "), topInfo=[layoutState.getOffset()=" + layoutState.getOffset() + " startSpace=" + startSpace + " secondStartSpace=" + secondStartSpace + " consumedGap=" + consumedGap + " lastUnconsumedSpace=" + lastUnconsumedSpace + "]"); } // We calculate everything with View's bounding box (which includes decor and margins) From 0390f7a0a07a557556feb709185510c74af510ea Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Wed, 17 Jul 2019 19:17:32 +0800 Subject: [PATCH 68/80] Fix sticky listener pass null on unticky. --- gradle.properties | 2 +- .../com/alibaba/android/vlayout/layout/StickyLayoutHelper.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4c0bae3a..9a3a1592 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.26 +VERSION_NAME=1.2.27 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index 1780d4a9..22907e7f 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -288,6 +288,7 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state } } + View stickyView = mFixView; // Not in normal flow if (!mDoNormalHandle && mFixView != null) { // already capture in layoutViews phase @@ -307,7 +308,7 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state if (stickyListener != null) { if (isLastStatusSticking && !isStickyNow()) { - stickyListener.onUnSticky(mPos, mFixView); + stickyListener.onUnSticky(mPos, stickyView); isLastStatusSticking = false; } else if (!isLastStatusSticking && isStickyNow()) { stickyListener.onSticky(mPos, mFixView); From 78ce269e569db52c35573c5c62d44a0c103dc657 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 22 Jul 2019 11:39:54 +0800 Subject: [PATCH 69/80] Remove bgColor --- gradle.properties | 2 +- .../alibaba/android/vlayout/layout/StickyLayoutHelper.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9a3a1592..a8da865a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.27 +VERSION_NAME=1.2.28 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index 22907e7f..35187e22 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -302,10 +302,6 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state fixLayoutStateInCase2(orientationHelper, recycler, startPosition, endPosition, helper); } - if (mFixView != null) { - mFixView.setBackgroundColor(mBgColor); - } - if (stickyListener != null) { if (isLastStatusSticking && !isStickyNow()) { stickyListener.onUnSticky(mPos, stickyView); From 70cd6e9ce8897c71bb0f714b8255e0cce8f4d1a4 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Wed, 24 Jul 2019 15:17:19 +0800 Subject: [PATCH 70/80] Fix item change should not clear layout info. --- gradle.properties | 2 +- .../android/vlayout/layout/StaggeredGridLayoutHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index a8da865a..bbbd5cda 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.28 +VERSION_NAME=1.2.29 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index d1df4a88..5e83250b 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -1034,7 +1034,7 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho @Override public void onItemsChanged(LayoutManagerHelper helper) { - mLazySpanLookup.clear(); +// mLazySpanLookup.clear(); } @Override From 99af2e08f0d21dfdb0555dd109e2f48515f41782 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 24 Sep 2019 17:41:25 +0800 Subject: [PATCH 71/80] Fix sticky listener callback not correct. --- gradle.properties | 2 +- .../com/alibaba/android/vlayout/layout/StickyLayoutHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index bbbd5cda..89805eee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.29 +VERSION_NAME=1.2.30 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index 35187e22..d271b178 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -63,7 +63,7 @@ public interface StickyListener { private boolean mDoNormalHandle = false; - private boolean isLastStatusSticking = true; + private boolean isLastStatusSticking = false; private StickyListener stickyListener; From 35444b5ae8419e3514b968714790f093ab026f95 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 26 Sep 2019 14:43:19 +0800 Subject: [PATCH 72/80] Avoid use of arrayMap which may cause class cast exception. --- gradle.properties | 2 +- .../alibaba/android/vlayout/extend/ViewLifeCycleHelper.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 89805eee..a5f24bd1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.30 +VERSION_NAME=1.2.31 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java index 6a248d42..7cd204ff 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/extend/ViewLifeCycleHelper.java @@ -6,6 +6,8 @@ import com.alibaba.android.vlayout.VirtualLayoutManager; +import java.util.HashMap; + public class ViewLifeCycleHelper { public enum STATUS { APPEARING, @@ -14,7 +16,7 @@ public enum STATUS { DISAPPEARED } - private ArrayMap mViewStatusMap = new ArrayMap<>(); + private HashMap mViewStatusMap = new HashMap<>(); private ViewLifeCycleListener mViewLifeCycleListener; From 5b2da5933c2f50242fda6fa0afa6fbe32fe24e0e Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 26 Sep 2019 15:49:27 +0800 Subject: [PATCH 73/80] Avoid use of arrayMap which may cause class cast exception. --- gradle.properties | 2 +- .../vlayout/layout/RangeGridLayoutHelper.java | 30 ++++++------ .../android/vlayout/layout/RangeStyle.java | 46 ++++++++++--------- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/gradle.properties b/gradle.properties index a5f24bd1..679fda26 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.31 +VERSION_NAME=1.2.32 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java index 4cf267e1..22e5c700 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeGridLayoutHelper.java @@ -42,6 +42,8 @@ import com.alibaba.android.vlayout.layout.GridLayoutHelper.SpanSizeLookup; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import static android.support.v7.widget.LinearLayoutManager.VERTICAL; @@ -917,13 +919,13 @@ public GridRangeStyle findRangeStyleByPosition(int position) { } private GridRangeStyle findRangeStyle(GridRangeStyle rangeStyle, int position){ - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - GridRangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); - Range range = rangeStyle.mChildren.keyAt(i); + for (Map.Entry, GridRangeStyle> entry : rangeStyle.mChildren.entrySet()) { + GridRangeStyle childRangeStyle = entry.getValue(); + Range range = entry.getKey(); if (!childRangeStyle.isChildrenEmpty()){ return findRangeStyle(childRangeStyle, position); } else if (range.contains(position)) { - return rangeStyle.mChildren.valueAt(i); + return childRangeStyle; } } return rangeStyle; @@ -932,11 +934,11 @@ private GridRangeStyle findRangeStyle(GridRangeStyle rangeStyle, int position){ public GridRangeStyle findSiblingStyleByPosition(int position) { GridRangeStyle rangeStyle = null; if (mParent != null) { - ArrayMap, GridRangeStyle> siblings = mParent.mChildren; - for (int i = 0, size = siblings.size(); i < size; i++) { - Range range = siblings.keyAt(i); + HashMap, GridRangeStyle> siblings = mParent.mChildren; + for (Map.Entry, GridRangeStyle> entry : siblings.entrySet()) { + Range range = entry.getKey(); if (range.contains(position)) { - GridRangeStyle childRangeStyle = siblings.valueAt(i); + GridRangeStyle childRangeStyle = entry.getValue(); if (!childRangeStyle.equals(this)) { rangeStyle = childRangeStyle; } @@ -949,8 +951,8 @@ public GridRangeStyle findSiblingStyleByPosition(int position) { public void onInvalidateSpanIndexCache() { mSpanSizeLookup.invalidateSpanIndexCache(); - for (int i = 0, size = mChildren.size(); i < size; i++) { - GridRangeStyle rangeStyle = mChildren.valueAt(i); + for (Map.Entry, GridRangeStyle> entry : mChildren.entrySet()) { + GridRangeStyle rangeStyle = entry.getValue(); rangeStyle.onInvalidateSpanIndexCache(); } } @@ -958,8 +960,8 @@ public void onInvalidateSpanIndexCache() { public static int computeEndAlignOffset(GridRangeStyle rangeStyle, boolean layoutInVertical) { int offset = layoutInVertical ? rangeStyle.mMarginBottom + rangeStyle.mPaddingBottom : rangeStyle.mMarginRight + rangeStyle.mPaddingRight; int endPosition = rangeStyle.getRange().getUpper().intValue(); - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - GridRangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, GridRangeStyle> entry : rangeStyle.mChildren.entrySet()) { + GridRangeStyle childRangeStyle = entry.getValue(); if (!childRangeStyle.isChildrenEmpty()){ offset += computeEndAlignOffset(childRangeStyle, layoutInVertical); }else if (childRangeStyle.mRange.getUpper().intValue() == endPosition) { @@ -974,8 +976,8 @@ public static int computeEndAlignOffset(GridRangeStyle rangeStyle, boolean layou public static int computeStartAlignOffset(GridRangeStyle rangeStyle, boolean layoutInVertical) { int offset = layoutInVertical ? -rangeStyle.mMarginTop - rangeStyle.mPaddingTop : -rangeStyle.mMarginLeft - rangeStyle.mPaddingLeft; int startPosition = rangeStyle.getRange().getLower().intValue(); - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - GridRangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, GridRangeStyle> entry : rangeStyle.mChildren.entrySet()) { + GridRangeStyle childRangeStyle = entry.getValue(); if (!childRangeStyle.isChildrenEmpty()){ //FIXME may compute the wrong start space here offset += computeStartAlignOffset(childRangeStyle, layoutInVertical); diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeStyle.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeStyle.java index 160a7bb6..0f53bb28 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeStyle.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/RangeStyle.java @@ -1,6 +1,8 @@ package com.alibaba.android.vlayout.layout; import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.Map; import com.alibaba.android.vlayout.LayoutManagerHelper; import com.alibaba.android.vlayout.OrientationHelperEx; @@ -43,7 +45,7 @@ public class RangeStyle { protected Range mRange; //TODO update data structure - protected ArrayMap, T> mChildren = new ArrayMap<>(); + protected HashMap, T> mChildren = new HashMap<>(); protected int mPaddingLeft; @@ -404,9 +406,9 @@ public boolean isLastPosition(int position) { public void setRange(int start, int end) { mRange = Range.create(start, end); if (!mChildren.isEmpty()) { - SimpleArrayMap, T> newMap = new SimpleArrayMap<>(); - for (int i = 0, size = mChildren.size(); i < size; i++) { - T rangeStyle = mChildren.valueAt(i); + HashMap, T> newMap = new HashMap<>(); + for (Map.Entry, T> entry : mChildren.entrySet()) { + T rangeStyle = entry.getValue(); int newStart = rangeStyle.getOriginStartOffset() + start; int newEnd = rangeStyle.getOriginEndOffset() + start; Range newRange = Range.create(newStart, newEnd); @@ -421,9 +423,9 @@ public void setRange(int start, int end) { public void beforeLayout(RecyclerView.Recycler recycler, RecyclerView.State state, LayoutManagerHelper helper) { if (!isChildrenEmpty()) { - for (int i = 0, size = mChildren.size(); i < size; i++) { - RangeStyle rangeStyle = mChildren.valueAt(i); - rangeStyle.beforeLayout(recycler, state, helper); + for (Map.Entry, T> entry : mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); + childRangeStyle.beforeLayout(recycler, state, helper); } } if (requireLayoutView()) { @@ -452,9 +454,9 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state LayoutManagerHelper helper) { if (!isChildrenEmpty()) { - for (int i = 0, size = mChildren.size(); i < size; i++) { - RangeStyle rangeStyle = mChildren.valueAt(i); - rangeStyle.afterLayout(recycler, state, startPosition, endPosition, scrolled, helper); + for (Map.Entry, T> entry : mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); + childRangeStyle.afterLayout(recycler, state, startPosition, endPosition, scrolled, helper); } } if (DEBUG) { @@ -521,8 +523,8 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state private void unionChildRegion(RangeStyle rangeStyle) { if (!rangeStyle.isChildrenEmpty()) { - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - RangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, T> entry : rangeStyle.mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); unionChildRegion(childRangeStyle); if (childRangeStyle.mLayoutView != null) { rangeStyle.mLayoutRegion.union(childRangeStyle.mLayoutView.getLeft(), childRangeStyle.mLayoutView.getTop(), @@ -534,8 +536,8 @@ private void unionChildRegion(RangeStyle rangeStyle) { private void removeChildViews(LayoutManagerHelper helper, RangeStyle rangeStyle) { if (!rangeStyle.isChildrenEmpty()) { - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - RangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, T> entry : rangeStyle.mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); removeChildViews(helper, childRangeStyle); } } @@ -551,8 +553,8 @@ private void removeChildViews(LayoutManagerHelper helper, RangeStyle rangeSty public void adjustLayout(int startPosition, int endPosition, LayoutManagerHelper helper) { if (!isChildrenEmpty()) { - for (int i = 0, size = mChildren.size(); i < size; i++) { - RangeStyle rangeStyle = mChildren.valueAt(i); + for (Map.Entry, T> entry : mChildren.entrySet()) { + RangeStyle rangeStyle = entry.getValue(); rangeStyle.adjustLayout(startPosition, endPosition, helper); } } @@ -605,8 +607,8 @@ private void hideLayoutViews(LayoutManagerHelper helper) { } private void hideChildLayoutViews(LayoutManagerHelper helper, RangeStyle rangeStyle) { - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - RangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, T> entry : rangeStyle.mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); if (!childRangeStyle.isChildrenEmpty()) { hideChildLayoutViews(helper, childRangeStyle); } @@ -628,8 +630,8 @@ public boolean requireLayoutView() { private boolean requireChildLayoutView(RangeStyle rangeStyle) { boolean self = rangeStyle.mBgColor != 0 || rangeStyle.mLayoutViewBindListener != null; - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - RangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, T> entry : rangeStyle.mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); if (!childRangeStyle.isChildrenEmpty()) { self |= requireChildLayoutView(childRangeStyle); } else { @@ -688,8 +690,8 @@ private void clearChild(LayoutManagerHelper helper, RangeStyle rangeStyle) { return; } - for (int i = 0, size = rangeStyle.mChildren.size(); i < size; i++) { - RangeStyle childRangeStyle = rangeStyle.mChildren.valueAt(i); + for (Map.Entry, T> entry : rangeStyle.mChildren.entrySet()) { + RangeStyle childRangeStyle = entry.getValue(); clearChild(helper, childRangeStyle); } } From dacf54f7915accb9ca1db43af5546e4e6aa3e7d6 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Tue, 15 Oct 2019 14:29:52 +0800 Subject: [PATCH 74/80] Fix sticky listener and npe. --- gradle.properties | 2 +- .../android/vlayout/layout/StaggeredGridLayoutHelper.java | 6 +++--- .../alibaba/android/vlayout/layout/StickyLayoutHelper.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 679fda26..583f884d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.32 +VERSION_NAME=1.2.33 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 5e83250b..265b1a4e 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -311,7 +311,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state } else { if (isEndLine) { end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? - mMarginBottom + mPaddingRight : mMarginRight + mPaddingRight); + mMarginBottom + mPaddingRight : mMarginRight + mPaddingRight); //Log.d(TAG, "endLine " + position + " " + end); } else { end = currentSpan.getStartLine(defaultNewViewLine, orientationHelper) - (layoutInVertical ? mVGap : mHGap); @@ -1054,7 +1054,7 @@ public void onRestoreInstanceState(Bundle bundle) { @Override public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { super.onOffsetChildrenVertical(dy, helper); - if (helper.getOrientation() == VERTICAL) { + if (helper.getOrientation() == VERTICAL && mSpans != null) { for (int i = 0, size = mSpans.length; i < size; i++) { Span span = mSpans[i]; span.onOffset(dy); @@ -1065,7 +1065,7 @@ public void onOffsetChildrenVertical(int dy, LayoutManagerHelper helper) { @Override public void onOffsetChildrenHorizontal(int dx, LayoutManagerHelper helper) { super.onOffsetChildrenHorizontal(dx, helper); - if (helper.getOrientation() == HORIZONTAL) { + if (helper.getOrientation() == HORIZONTAL && mSpans != null) { for (int i = 0, size = mSpans.length; i < size; i++) { Span span = mSpans[i]; span.onOffset(dx); diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index d271b178..fd4c124b 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -85,7 +85,7 @@ public void setOffset(int offset) { } public boolean isStickyNow() { - return !mDoNormalHandle; + return !mDoNormalHandle && mFixView != null; } @Override From b7f46425e756162bf14fcc8e0c2d35e891810ef0 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Mon, 16 Dec 2019 16:29:23 +0800 Subject: [PATCH 75/80] Fix mSpans in StaggeredGridLayoutHelper may be null cause exception. --- .../vlayout/example/VLayoutActivity.java | 150 +++++++++--------- gradle.properties | 2 +- .../layout/StaggeredGridLayoutHelper.java | 69 ++++---- 3 files changed, 118 insertions(+), 103 deletions(-) diff --git a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java index dca43f00..daeb7975 100644 --- a/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java +++ b/examples/src/main/java/com/alibaba/android/vlayout/example/VLayoutActivity.java @@ -319,81 +319,81 @@ public void onBindViewHolder(MainViewHolder holder, int position) { }); } - { - RangeGridLayoutHelper layoutHelper = new RangeGridLayoutHelper(4); - layoutHelper.setBgColor(Color.GREEN); - layoutHelper.setWeights(new float[]{20f, 26.665f}); - layoutHelper.setPadding(15, 15, 15, 15); - layoutHelper.setMargin(15, 50, 15, 150); - layoutHelper.setHGap(10); - layoutHelper.setVGap(10); - GridRangeStyle rangeStyle = new GridRangeStyle(); - rangeStyle.setBgColor(Color.RED); - rangeStyle.setSpanCount(2); - rangeStyle.setWeights(new float[]{46.665f}); - rangeStyle.setPadding(15, 15, 15, 15); - rangeStyle.setMargin(15, 15, 15, 15); - rangeStyle.setHGap(5); - rangeStyle.setVGap(5); - layoutHelper.addRangeStyle(0, 7, rangeStyle); - - GridRangeStyle rangeStyle1 = new GridRangeStyle(); - rangeStyle1.setBgColor(Color.YELLOW); - rangeStyle1.setSpanCount(2); - rangeStyle1.setWeights(new float[]{46.665f}); - rangeStyle1.setPadding(15, 15, 15, 15); - rangeStyle1.setMargin(15, 15, 15, 15); - rangeStyle1.setHGap(5); - rangeStyle1.setVGap(5); - layoutHelper.addRangeStyle(8, 15, rangeStyle1); - - GridRangeStyle rangeStyle2 = new GridRangeStyle(); - rangeStyle2.setBgColor(Color.CYAN); - rangeStyle2.setSpanCount(2); - rangeStyle2.setWeights(new float[]{46.665f}); - rangeStyle2.setPadding(15, 15, 15, 15); - rangeStyle2.setMargin(15, 15, 15, 15); - rangeStyle2.setHGap(5); - rangeStyle2.setVGap(5); - layoutHelper.addRangeStyle(16, 22, rangeStyle2); - GridRangeStyle rangeStyle3 = new GridRangeStyle(); - rangeStyle3.setBgColor(Color.DKGRAY); - rangeStyle3.setSpanCount(1); - rangeStyle3.setWeights(new float[]{46.665f}); - rangeStyle3.setPadding(15, 15, 15, 15); - rangeStyle3.setMargin(15, 15, 15, 15); - rangeStyle3.setHGap(5); - rangeStyle3.setVGap(5); - rangeStyle2.addChildRangeStyle(0, 2, rangeStyle3); - GridRangeStyle rangeStyle4 = new GridRangeStyle(); - rangeStyle4.setBgColor(Color.BLUE); - rangeStyle4.setSpanCount(2); - rangeStyle4.setWeights(new float[]{46.665f}); - rangeStyle4.setPadding(15, 15, 15, 15); - rangeStyle4.setMargin(15, 15, 15, 15); - rangeStyle4.setHGap(5); - rangeStyle4.setVGap(5); - rangeStyle2.addChildRangeStyle(3, 6, rangeStyle4); - - GridRangeStyle rangeStyle5 = new GridRangeStyle(); - rangeStyle5.setBgColor(Color.RED); - rangeStyle5.setSpanCount(2); - rangeStyle5.setPadding(15, 15, 15, 15); - rangeStyle5.setMargin(15, 15, 15, 15); - rangeStyle5.setHGap(5); - rangeStyle5.setVGap(5); - layoutHelper.addRangeStyle(23, 30, rangeStyle5); - GridRangeStyle rangeStyle6 = new GridRangeStyle(); - rangeStyle6.setBgColor(Color.MAGENTA); - rangeStyle6.setSpanCount(2); - rangeStyle6.setPadding(15, 15, 15, 15); - rangeStyle6.setMargin(15, 15, 15, 15); - rangeStyle6.setHGap(5); - rangeStyle6.setVGap(5); - rangeStyle5.addChildRangeStyle(0, 7, rangeStyle6); - - adapters.add(new SubAdapter(this, layoutHelper, 23)); - } +// { +// RangeGridLayoutHelper layoutHelper = new RangeGridLayoutHelper(4); +// layoutHelper.setBgColor(Color.GREEN); +// layoutHelper.setWeights(new float[]{20f, 26.665f}); +// layoutHelper.setPadding(15, 15, 15, 15); +// layoutHelper.setMargin(15, 50, 15, 150); +// layoutHelper.setHGap(10); +// layoutHelper.setVGap(10); +// GridRangeStyle rangeStyle = new GridRangeStyle(); +// rangeStyle.setBgColor(Color.RED); +// rangeStyle.setSpanCount(2); +// rangeStyle.setWeights(new float[]{46.665f}); +// rangeStyle.setPadding(15, 15, 15, 15); +// rangeStyle.setMargin(15, 15, 15, 15); +// rangeStyle.setHGap(5); +// rangeStyle.setVGap(5); +// layoutHelper.addRangeStyle(0, 7, rangeStyle); +// +// GridRangeStyle rangeStyle1 = new GridRangeStyle(); +// rangeStyle1.setBgColor(Color.YELLOW); +// rangeStyle1.setSpanCount(2); +// rangeStyle1.setWeights(new float[]{46.665f}); +// rangeStyle1.setPadding(15, 15, 15, 15); +// rangeStyle1.setMargin(15, 15, 15, 15); +// rangeStyle1.setHGap(5); +// rangeStyle1.setVGap(5); +// layoutHelper.addRangeStyle(8, 15, rangeStyle1); +// +// GridRangeStyle rangeStyle2 = new GridRangeStyle(); +// rangeStyle2.setBgColor(Color.CYAN); +// rangeStyle2.setSpanCount(2); +// rangeStyle2.setWeights(new float[]{46.665f}); +// rangeStyle2.setPadding(15, 15, 15, 15); +// rangeStyle2.setMargin(15, 15, 15, 15); +// rangeStyle2.setHGap(5); +// rangeStyle2.setVGap(5); +// layoutHelper.addRangeStyle(16, 22, rangeStyle2); +// GridRangeStyle rangeStyle3 = new GridRangeStyle(); +// rangeStyle3.setBgColor(Color.DKGRAY); +// rangeStyle3.setSpanCount(1); +// rangeStyle3.setWeights(new float[]{46.665f}); +// rangeStyle3.setPadding(15, 15, 15, 15); +// rangeStyle3.setMargin(15, 15, 15, 15); +// rangeStyle3.setHGap(5); +// rangeStyle3.setVGap(5); +// rangeStyle2.addChildRangeStyle(0, 2, rangeStyle3); +// GridRangeStyle rangeStyle4 = new GridRangeStyle(); +// rangeStyle4.setBgColor(Color.BLUE); +// rangeStyle4.setSpanCount(2); +// rangeStyle4.setWeights(new float[]{46.665f}); +// rangeStyle4.setPadding(15, 15, 15, 15); +// rangeStyle4.setMargin(15, 15, 15, 15); +// rangeStyle4.setHGap(5); +// rangeStyle4.setVGap(5); +// rangeStyle2.addChildRangeStyle(3, 6, rangeStyle4); +// +// GridRangeStyle rangeStyle5 = new GridRangeStyle(); +// rangeStyle5.setBgColor(Color.RED); +// rangeStyle5.setSpanCount(2); +// rangeStyle5.setPadding(15, 15, 15, 15); +// rangeStyle5.setMargin(15, 15, 15, 15); +// rangeStyle5.setHGap(5); +// rangeStyle5.setVGap(5); +// layoutHelper.addRangeStyle(23, 30, rangeStyle5); +// GridRangeStyle rangeStyle6 = new GridRangeStyle(); +// rangeStyle6.setBgColor(Color.MAGENTA); +// rangeStyle6.setSpanCount(2); +// rangeStyle6.setPadding(15, 15, 15, 15); +// rangeStyle6.setMargin(15, 15, 15, 15); +// rangeStyle6.setHGap(5); +// rangeStyle6.setVGap(5); +// rangeStyle5.addChildRangeStyle(0, 7, rangeStyle6); +// +// adapters.add(new SubAdapter(this, layoutHelper, 23)); +// } { SingleLayoutHelper layoutHelper = new SingleLayoutHelper(); diff --git a/gradle.properties b/gradle.properties index 583f884d..e530dc52 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.33 +VERSION_NAME=1.2.36 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java index 265b1a4e..42c27d2d 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StaggeredGridLayoutHelper.java @@ -355,7 +355,7 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state handleStateOnResult(result, view); } - if (isOutOfRange(layoutState.getCurrentPosition())) { + if (isOutOfRange(layoutState.getCurrentPosition()) && mSpans != null) { // reach the end of layout, cache the gap // TODO: how to retain gap if (layoutState.getLayoutDirection() == LayoutStateWrapper.LAYOUT_START) { @@ -596,9 +596,11 @@ private void checkForGaps() { //FIXME do not clear loopup, may cause lane error while scroll //mLazySpanLookup.clear(); - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - span.setLine(alignLine); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + span.setLine(alignLine); + } } layoutManager.requestSimpleAnimationsInNextLayout(); @@ -622,10 +624,12 @@ private View hasGapsToFix(VirtualLayoutManager layoutManager, final int position BitSet mSpansToCheck = new BitSet(mNumLanes); mSpansToCheck.set(0, mNumLanes, true); - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - if (span.mViews.size() != 0 && checkSpanForGap(span, layoutManager, alignLine)) { - return layoutManager.getReverseLayout() ? span.mViews.get(span.mViews.size() - 1) : span.mViews.get(0); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + if (span.mViews.size() != 0 && checkSpanForGap(span, layoutManager, alignLine)) { + return layoutManager.getReverseLayout() ? span.mViews.get(span.mViews.size() - 1) : span.mViews.get(0); + } } } @@ -709,6 +713,9 @@ private void recycleFromEnd(RecyclerView.Recycler recycler, int line, LayoutMana private Span findSpan(int position, View child, boolean isStart) { int span = mLazySpanLookup.getSpan(position); + if (mSpans == null){ + return null; + } if (span >= 0 && span < mSpans.length) { Span sp = mSpans[span]; if (isStart && sp.findStart(child)) { @@ -930,9 +937,11 @@ public void onRefreshLayout(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "onRefreshLayout span.clear()"); } - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - span.clear(); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + span.clear(); + } } } } @@ -964,22 +973,26 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.clear()"); } - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - span.clear(); - span.setLine(anchorInfo.coordinate); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + span.clear(); + span.setLine(anchorInfo.coordinate); + } } } else { int anchorPos = anchorInfo.layoutFromEnd ? Integer.MIN_VALUE : Integer.MAX_VALUE; - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - if (!span.mViews.isEmpty()) { - if (anchorInfo.layoutFromEnd) { - View view = span.mViews.get(span.mViews.size() - 1); - anchorPos = Math.max(anchorPos, helper.getPosition(view)); - } else { - View view = span.mViews.get(0); - anchorPos = Math.min(anchorPos, helper.getPosition(view)); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + if (!span.mViews.isEmpty()) { + if (anchorInfo.layoutFromEnd) { + View view = span.mViews.get(span.mViews.size() - 1); + anchorPos = Math.max(anchorPos, helper.getPosition(view)); + } else { + View view = span.mViews.get(0); + anchorPos = Math.min(anchorPos, helper.getPosition(view)); + } } } } @@ -1024,9 +1037,11 @@ public void checkAnchorInfo(RecyclerView.State state, VirtualLayoutManager.Ancho if (BuildConfig.DEBUG) { Log.d(TAG, "checkAnchorInfo span.cacheReferenceLineAndClear()"); } - for (int i = 0, size = mSpans.length; i < size; i++) { - Span span = mSpans[i]; - span.cacheReferenceLineAndClear(helper.getReverseLayout() ^ anchorInfo.layoutFromEnd, offset, orientationHelper); + if (mSpans != null) { + for (int i = 0, size = mSpans.length; i < size; i++) { + Span span = mSpans[i]; + span.cacheReferenceLineAndClear(helper.getReverseLayout() ^ anchorInfo.layoutFromEnd, offset, orientationHelper); + } } } } From 50e63cc47f4e7bb353e65108436d25cca7ae8565 Mon Sep 17 00:00:00 2001 From: MikeAfc Date: Thu, 9 Jan 2020 16:21:46 +0800 Subject: [PATCH 76/80] Fix layout calculate in horizontal mode. --- gradle.properties | 2 +- .../com/alibaba/android/vlayout/layout/BaseLayoutHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e530dc52..ac828aee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.36 +VERSION_NAME=1.2.37 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java index 13980db8..5c77b8c3 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/BaseLayoutHelper.java @@ -206,7 +206,7 @@ public void afterLayout(RecyclerView.Recycler recycler, RecyclerView.State state mLayoutRegion.right = helper.getContentWidth() - helper.getPaddingRight() - mMarginRight; } else { mLayoutRegion.top = helper.getPaddingTop() + mMarginTop; - mLayoutRegion.bottom = helper.getContentWidth() - helper.getPaddingBottom() - mMarginBottom; + mLayoutRegion.bottom = helper.getContentHeight() - helper.getPaddingBottom() - mMarginBottom; } bindLayoutView(mLayoutView); From f394eff9beb5b13872d4637fe148e767f2f0320d Mon Sep 17 00:00:00 2001 From: skycrown Date: Fri, 21 Feb 2020 12:43:07 +0800 Subject: [PATCH 77/80] add stackable sticky views support --- gradle.properties | 2 +- .../vlayout/layout/StickyLayoutHelper.java | 49 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index ac828aee..47f6b653 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.37 +VERSION_NAME=1.2.38 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java index fd4c124b..3556eb2a 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/layout/StickyLayoutHelper.java @@ -35,6 +35,8 @@ import com.alibaba.android.vlayout.VirtualLayoutManager; import com.alibaba.android.vlayout.VirtualLayoutManager.LayoutStateWrapper; +import java.util.List; + import static android.support.v7.widget.LinearLayoutManager.VERTICAL; @@ -51,6 +53,10 @@ public interface StickyListener { void onUnSticky(int pos, View view); } + public interface Stackable { + boolean enable(); + } + private static final String TAG = "StickyStartLayoutHelper"; private int mPos = -1; @@ -66,6 +72,7 @@ public interface StickyListener { private boolean isLastStatusSticking = false; private StickyListener stickyListener; + private Stackable mStackable; public StickyLayoutHelper() { this(true); @@ -230,7 +237,6 @@ public void layoutViews(RecyclerView.Recycler recycler, RecyclerView.State state if (mDoNormalHandle) { helper.addChildView(layoutState, view); handleStateOnResult(result, view); - mFixView = null; } else { // result.mConsumed += mOffset; } @@ -373,7 +379,8 @@ private void fixLayoutStateInCase1(OrientationHelperEx orientationHelper, Recycl if ((mStickyStart && endPosition >= mPos) || (!mStickyStart && startPosition <= mPos)) { int consumed = orientationHelper.getDecoratedMeasurement(mFixView); boolean layoutInVertical = helper.getOrientation() == VERTICAL; - final int startAdjust = layoutInVertical ? mAdjuster.top : mAdjuster.left; + 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; @@ -523,7 +530,8 @@ private void fixLayoutStateInCase2(OrientationHelperEx orientationHelper, Recycl boolean normalHandle = false; boolean layoutInVertical = helper.getOrientation() == VERTICAL; - final int startAdjust = layoutInVertical ? mAdjuster.top : mAdjuster.left; + 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)) { @@ -755,5 +763,40 @@ private void doMeasure(View view, LayoutManagerHelper helper) { public void setStickyListener(StickyListener stickyListener) { this.stickyListener = stickyListener; } + + public void setStackable(Stackable stackable) { + mStackable = stackable; + } + + /** + * + * get extra top offset when there are multi-sticky views at the top of current view + * in order to avoid views overlap + * the offset value is equal to total sticky views' height. + * @param helper + */ + private int getExtraTopOffset(LayoutManagerHelper helper) { + if (mStackable == null || !mStackable.enable()) { + return 0; + } + + int offset = 0; + if (helper instanceof VirtualLayoutManager){ + List helperList = ((VirtualLayoutManager) helper).getLayoutHelpers(); + for (LayoutHelper helperItem : helperList) { + if (helperItem.isFixLayout()) { + if (helperItem.getRange().getUpper() < this.getRange().getLower()) { + View view = helperItem.getFixedView(); + if (view != null) { + offset += view.getHeight(); + } + } + } + } + + } + + return offset; + } } From 54687a7eb56a920dd1d3606585ce4ef15e716c6a Mon Sep 17 00:00:00 2001 From: skycrown Date: Wed, 13 May 2020 22:28:42 +0800 Subject: [PATCH 78/80] fix item's width and height were replaced by default params. --- gradle.properties | 2 +- .../alibaba/android/vlayout/RecyclablePagerAdapter.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 47f6b653..e2f89383 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,7 +44,7 @@ GROUP=com.alibaba.android ARTIFACT=vlayout VERSION=1 -VERSION_NAME=1.2.38 +VERSION_NAME=1.2.39 PACKAGING_TYPE=aar useNewSupportLibrary=true systemProp.compileSdkVersion=26 diff --git a/vlayout/src/main/java/com/alibaba/android/vlayout/RecyclablePagerAdapter.java b/vlayout/src/main/java/com/alibaba/android/vlayout/RecyclablePagerAdapter.java index 8bc39cf2..2f88e85f 100644 --- a/vlayout/src/main/java/com/alibaba/android/vlayout/RecyclablePagerAdapter.java +++ b/vlayout/src/main/java/com/alibaba/android/vlayout/RecyclablePagerAdapter.java @@ -81,7 +81,14 @@ public Object instantiateItem(ViewGroup container, int position) { //so the attributes of layoutParam such as widthFactor and position will also be reused, //while these attributes should be reset to default value during reused. //Considering ViewPager.LayoutParams has a few inner attributes which could not be modify outside, we provide a new instance here - container.addView(holder.itemView, new ViewPager.LayoutParams()); + + ViewPager.LayoutParams layoutParams = new ViewPager.LayoutParams(); + if (holder.itemView.getLayoutParams() != null) { + layoutParams.width = holder.itemView.getLayoutParams().width; + layoutParams.height = holder.itemView.getLayoutParams().height; + } + + container.addView(holder.itemView, layoutParams); return holder; } From 136092943e2951f1ad636de1ddb4ce7fdcd4b30b Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 14 Jul 2021 12:40:03 +0800 Subject: [PATCH 79/80] Update README.md update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 76b41b7f..28252a0a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# Attention. This project is not maintained any more !!! + # vlayout [中文文档](README-ch.md) From 00d6be0a1fa89c2f54ca923d2ea2e34d279d289e Mon Sep 17 00:00:00 2001 From: Xiaolong Hong Date: Wed, 14 Jul 2021 12:40:34 +0800 Subject: [PATCH 80/80] Update README-ch.md update readme --- README-ch.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README-ch.md b/README-ch.md index 0425c1f2..ae4005ca 100644 --- a/README-ch.md +++ b/README-ch.md @@ -1,3 +1,5 @@ +# 注意,该项目停止维护!!! + # vlayout [English Document](README.md)