From 3211f7887b550e5e1745771f2c66a69586e1ef3f Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Sun, 24 Jan 2016 15:58:36 +0800 Subject: [PATCH] feat:support ItemDecorations --- .../MaterialDemoActivity.java | 2 +- .../SpacesItemDecoration.java | 31 +++++++++++ .../main/res/layout/fragment_cheese_list.xml | 2 +- .../recyclerviewpager/RecyclerViewPager.java | 55 ++++++++++++++++++- .../recyclerviewpager/TabLayoutSupport.java | 10 +++- 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/SpacesItemDecoration.java diff --git a/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/MaterialDemoActivity.java b/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/MaterialDemoActivity.java index c84bb82..5ccd16d 100644 --- a/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/MaterialDemoActivity.java +++ b/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/MaterialDemoActivity.java @@ -44,7 +44,7 @@ protected void initViewPager() { mRecyclerView.setAdapter(mAdapter); mRecyclerView.setHasFixedSize(true); mRecyclerView.setLongClickable(true); - + mRecyclerView.addItemDecoration(new SpacesItemDecoration(50, mRecyclerView.getAdapter().getItemCount())); mRecyclerView.addOnPageChangedListener(new RecyclerViewPager.OnPageChangedListener() { @Override public void OnPageChanged(int oldPosition, int newPosition) { diff --git a/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/SpacesItemDecoration.java b/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/SpacesItemDecoration.java new file mode 100644 index 0000000..7605dcc --- /dev/null +++ b/app/src/main/java/com/lsjwzh/widget/recyclerviewpagerdeomo/SpacesItemDecoration.java @@ -0,0 +1,31 @@ +package com.lsjwzh.widget.recyclerviewpagerdeomo; + +import android.graphics.Rect; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +public class SpacesItemDecoration extends RecyclerView.ItemDecoration { + private final int mColumnCount; + private final int mSpace; + + public SpacesItemDecoration(int space, int columnCount) { + this.mSpace = space; + this.mColumnCount = columnCount; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + outRect.bottom = mSpace; + // Add top margin only for the first item to avoid double mSpace between items + if (parent.getChildLayoutPosition(view) == mColumnCount - 1) { + outRect.right = 0; + } else { + outRect.right = mSpace / 2; + } + if (parent.getChildLayoutPosition(view) == 0) { + outRect.left = 0; + } else { + outRect.left = mSpace / 2; + } + } +} diff --git a/app/src/main/res/layout/fragment_cheese_list.xml b/app/src/main/res/layout/fragment_cheese_list.xml index 20b4c2e..7a95db0 100644 --- a/app/src/main/res/layout/fragment_cheese_list.xml +++ b/app/src/main/res/layout/fragment_cheese_list.xml @@ -17,4 +17,4 @@ \ No newline at end of file + android:layout_height="match_parent" /> diff --git a/lib/src/main/java/com/lsjwzh/widget/recyclerviewpager/RecyclerViewPager.java b/lib/src/main/java/com/lsjwzh/widget/recyclerviewpager/RecyclerViewPager.java index 812f618..7445931 100644 --- a/lib/src/main/java/com/lsjwzh/widget/recyclerviewpager/RecyclerViewPager.java +++ b/lib/src/main/java/com/lsjwzh/widget/recyclerviewpager/RecyclerViewPager.java @@ -6,10 +6,12 @@ import android.content.Context; import android.content.res.TypedArray; +import android.graphics.PointF; import android.os.Build; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.LinearSmoothScroller; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.Log; @@ -173,7 +175,54 @@ public void smoothScrollToPosition(int position) { Log.d("@", "smoothScrollToPosition:" + position); } mSmoothScrollTargetPosition = position; - super.smoothScrollToPosition(position); + if (getLayoutManager() != null && getLayoutManager() instanceof LinearLayoutManager) { + // exclude item decoration + LinearSmoothScroller linearSmoothScroller = + new LinearSmoothScroller(getContext()) { + @Override + public PointF computeScrollVectorForPosition(int targetPosition) { + if (getLayoutManager() == null) { + return null; + } + return ((LinearLayoutManager) getLayoutManager()) + .computeScrollVectorForPosition(targetPosition); + } + + @Override + protected void onTargetFound(View targetView, RecyclerView.State state, Action action) { + if (getLayoutManager() == null) { + return; + } + int dx = calculateDxToMakeVisible(targetView, + getHorizontalSnapPreference()); + int dy = calculateDyToMakeVisible(targetView, + getVerticalSnapPreference()); + if (dx > 0) { + dx = dx - getLayoutManager() + .getLeftDecorationWidth(targetView); + } else { + dx = dx + getLayoutManager() + .getRightDecorationWidth(targetView); + } + if (dy > 0) { + dy = dy - getLayoutManager() + .getTopDecorationHeight(targetView); + } else { + dy = dy + getLayoutManager() + .getBottomDecorationHeight(targetView); + } + final int distance = (int) Math.sqrt(dx * dx + dy * dy); + final int time = calculateTimeForDeceleration(distance); + if (time > 0) { + action.update(-dx, -dy, time, mDecelerateInterpolator); + } + } + }; + linearSmoothScroller.setTargetPosition(position); + getLayoutManager().startSmoothScroll(linearSmoothScroller); + } else { + super.smoothScrollToPosition(position); + } } @Override @@ -256,7 +305,7 @@ protected void adjustPositionX(int velocityX) { else targetPosition++; } else if (mTouchSpan < centerXChild.getWidth() * -mTriggerOffset && targetPosition != mViewPagerAdapter.getItemCount() - 1) { if (!reverseLayout) targetPosition++; - else targetPosition --; + else targetPosition--; } } } @@ -401,7 +450,7 @@ public void onScrollStateChanged(int state) { // if user is tending to cancel paging action, don't perform position changing if (spanX > mCurView.getWidth() * mTriggerOffset && mCurView.getLeft() >= mMaxLeftWhenDragging) { if (!reverseLayout) targetPosition--; - else targetPosition ++; + else targetPosition++; } else if (spanX < mCurView.getWidth() * -mTriggerOffset && mCurView.getLeft() <= mMinLeftWhenDragging) { if (!reverseLayout) targetPosition++; else targetPosition--; diff --git a/tablayoutsupport/src/main/java/com/lsjwzh/widget/recyclerviewpager/TabLayoutSupport.java b/tablayoutsupport/src/main/java/com/lsjwzh/widget/recyclerviewpager/TabLayoutSupport.java index 750944e..5dab808 100644 --- a/tablayoutsupport/src/main/java/com/lsjwzh/widget/recyclerviewpager/TabLayoutSupport.java +++ b/tablayoutsupport/src/main/java/com/lsjwzh/widget/recyclerviewpager/TabLayoutSupport.java @@ -6,6 +6,7 @@ import android.support.design.widget.TabLayout; import android.support.v7.widget.RecyclerView; import android.util.Log; +import android.view.View; public class TabLayoutSupport { @@ -76,9 +77,12 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { final int pagerWidth = recyclerView.getWidth() - recyclerView.getPaddingLeft() - recyclerView.getPaddingRight(); - int centerChildPosition = viewPager.getChildAdapterPosition(ViewUtils.getCenterXChild - (viewPager)); - float offset = mPagerLeftBeforeScroll - ViewUtils.getCenterXChild(viewPager).getLeft() + final View centerXChild = ViewUtils.getCenterXChild(viewPager); + if (centerXChild == null) { + return; + } + int centerChildPosition = viewPager.getChildAdapterPosition(centerXChild); + float offset = mPagerLeftBeforeScroll - centerXChild.getLeft() + pagerWidth * (centerChildPosition - mPositionBeforeScroll); final float positionOffset = offset * 1f / pagerWidth; if (tabLayout != null) {