Make RecyclerView smooth scroll speed customizable

This commit is contained in:
seven332 committed 2015-05-12 19:35:29 +08:00
1 parent 224760abf6
commit dae22d0284
17 files changed
+17367 -4

No files matched your search

@@ -350,7 +350,9 @@ public class ContentLayout extends FrameLayout {
if (mCurrentTaskType == TYPE_PRE_PAGE_KEEP_POS) {
mFirstIndex += pageVolume;
mLastIndex += pageVolume;
// TODO
mRecyclerView.stopScroll();
LayoutManagerUtils.smoothScrollToPosition(mLayoutManager, mContext, mFirstIndex - 1, 100);
} else {
mCurrentPage = mFirstPage;
mFirstIndex = 0;
@@ -464,7 +466,8 @@ public class ContentLayout extends FrameLayout {
if (mViewTransition.getShownViewIndex() == 0) {
// Go to top
mRecyclerView.stopScroll();
mLayoutManager.smoothScrollToPosition(mRecyclerView, null, 0);
LayoutManagerUtils.scrollToPositionWithOffset(mLayoutManager, 0, 0);
onScrollToPosition();
// Show header refresh
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
@@ -15,10 +15,14 @@
package com.hippo.util;
import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import com.hippo.widget.recyclerview.SimpleSmoothScroller;
public final class LayoutManagerUtils {
public static void scrollToPositionWithOffset(
@@ -33,6 +37,47 @@ public final class LayoutManagerUtils {
}
}
public static void smoothScrollToPosition(
RecyclerView.LayoutManager layoutManager, Context context, int position) {
smoothScrollToPosition(layoutManager, context, position, -1);
}
public static void smoothScrollToPosition(
RecyclerView.LayoutManager layoutManager, Context context, int position,
int millisecondsPerInch) {
SimpleSmoothScroller smoothScroller;
if (layoutManager instanceof LinearLayoutManager) {
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
smoothScroller = new SimpleSmoothScroller(context, millisecondsPerInch) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return linearLayoutManager.computeScrollVectorForPosition(targetPosition);
}
};
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
final StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
smoothScroller = new SimpleSmoothScroller(context, millisecondsPerInch) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
final int direction = staggeredGridLayoutManager.calculateScrollDirectionForPosition(targetPosition);
if (direction == 0) {
return null;
}
if (staggeredGridLayoutManager.getOrientation() == StaggeredGridLayoutManager.HORIZONTAL) {
return new PointF(direction, 0);
} else {
return new PointF(0, direction);
}
}
};
} else {
throw new IllegalStateException("Can't do smoothScrollToPosition for " +
layoutManager.getClass().getName());
}
smoothScroller.setTargetPosition(position);
layoutManager.startSmoothScroll(smoothScroller);
}
public static int getFirstVisibleItemPostion(RecyclerView.LayoutManager layoutManager) {
if (layoutManager instanceof LinearLayoutManager) {
return ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.widget.recyclerview;
import android.content.Context;
import android.support.v7.widget.LinearSmoothScroller;
public abstract class SimpleSmoothScroller extends LinearSmoothScroller {
private float mMillisecondsPerPx;
public SimpleSmoothScroller(Context context, float millisecondsPerInch) {
super(context);
mMillisecondsPerPx = millisecondsPerInch / context.getResources().getDisplayMetrics().densityDpi;
}
@Override
protected int calculateTimeForScrolling(int dx) {
if (mMillisecondsPerPx <= 0) {
return super.calculateTimeForScrolling(dx);
} else {
return (int) Math.ceil(Math.abs(dx) * mMillisecondsPerPx);
}
}
}