使用LinearSmoothScroller类可以实现滑动
LinearSmoothScroller scroller = new LinearSmoothScroller(getContext()) {
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 2000 / displayMetrics.densityDpi;
}
};
scroller.setTargetPosition(mRecyclerView.getAdapter().getItemCount() - 1);
mRecyclerView.getLayoutManager().startSmoothScroll(scroller);
上面的代码就可以实现自定义滑动速度到列表底部,其中calculateSpeedPerPixel方法返回的是每像素滑动需要的时间(ms),2000 / displayMetrics.densityDpi 的结果是表示每个逻辑像素(dpi)滑动需要的时间,使用逻辑像素可以在不同分辨率屏幕的设备上滑动速度基本保持一致。
问题1 滑动到最后有个减速滑动的效果,这个是LinearSmoothScroller默认实现的(前面匀速滑动,到最后一点点减速滑动),要保持全程匀速滑动可以使用以下代码
LinearSmoothScroller scroller = new LinearSmoothScroller(getContext()) {
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 2000 / displayMetrics.densityDpi;
}
@Override
protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
final int dx = calculateDxToMakeVisible(targetView, getHorizontalSnapPreference());
final int dy = calculateDyToMakeVisible(targetView, getVerticalSnapPreference());
final int distance = (int) Math.sqrt(dx * dx + dy * dy);
final int time = calculateTimeForDeceleration(distance);
if (time > 0) {
action.update(-dx, -dy, time, mLinearInterpolator);
}
}
@Override
protected int calculateTimeForDeceleration(int dx) {
return (int) Math.ceil(calculateTimeForScrolling(dx));
}
};
scroller.setTargetPosition(mRecyclerView.getAdapter().getItemCount() - 1);
mRecyclerView.getLayoutManager().startSmoothScroll(scroller);
复写onTargetFound和calculateTimeForDeceleration方法即可
问题2 在最后一个item高度超过屏幕的情况下,且当前显示的是最后一个item时,使用mRecyclerView.getLayoutManager().startSmoothScroll(scroller)会出现反向滑动的情况,这个和系统滑动逻辑有关。
其实只要保证最后一个item高度不要超过屏幕高即可。提供一个简单的解决办法,在列表的底部添加一个空白的item(高度可以1px)。