亲爱的我已经设法通过自定义线性布局管理器使用scrollToPosition方法来控制滚动速度。
但是我使用了scrollBy(int dx,int dy)方法,滚动速度仍然是recyclerview速度的默认滚动速度。
任何想法如何更改此特定方法的滚动速度?
这是我的布局代码:
package com.arabiaweather.maater.screens.livesatellite.components
import android.content.Context
import android.graphics.PointF
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.LinearSmoothScroller
import android.support.v7.widget.RecyclerView
import android.util.DisplayMetrics
class CustomLinearLayoutManager : LinearLayoutManager {
var millisPerInch = 250.0f
constructor(context: Context) : super(context) {}
constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout) {}
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) {
val linearSmoothScroller = object : LinearSmoothScroller(recyclerView.context) {
override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
return this@CustomLinearLayoutManager
.computeScrollVectorForPosition(targetPosition)
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return millisPerInch / displayMetrics.densityDpi
}
}
linearSmoothScroller.targetPosition = position
startSmoothScroll(linearSmoothScroller)
}
override fun startSmoothScroll(smoothScroller: RecyclerView.SmoothScroller?) {
super.startSmoothScroll(smoothScroller)
}
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
super.scrollToPositionWithOffset(position, offset)
}
}
答案 0 :(得分:0)
我认为没有办法。
看一下Android代码,我发现ViewFlinger类包含一个允许通过距离和速度设置滚动的方法:
class ViewFlinger implements Runnable {
...
...
public void smoothScrollBy(int dx, int dy, int vx, int vy) {
smoothScrollBy(dx, dy, computeScrollDuration(dx, dy, vx, vy));
}
}
不幸的是,由于RecyclerView.mViewFlinger是私有的,因此我看不到从RecyclerView访问此功能的方法。我希望有一种方法可以从继承的类中访问它。
另一种方法是扩展ViewFlinger类并覆盖函数computeScrollDuration(),但我也没有找到一种方法(ViewFlinger类在RecyclerView中是程序包私有的)
private int computeScrollDuration(int dx, int dy, int vx, int vy) {
final int absDx = Math.abs(dx);
final int absDy = Math.abs(dy);
final boolean horizontal = absDx > absDy;
final int velocity = (int) Math.sqrt(vx * vx + vy * vy);
final int delta = (int) Math.sqrt(dx * dx + dy * dy);
final int containerSize = horizontal ? getWidth() : getHeight();
final int halfContainerSize = containerSize / 2;
final float distanceRatio = Math.min(1.f, 1.f * delta / containerSize);
final float distance = halfContainerSize + halfContainerSize
* distanceInfluenceForSnapDuration(distanceRatio);
final int duration;
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
} else {
float absDelta = (float) (horizontal ? absDx : absDy);
duration = (int) (((absDelta / containerSize) + 1) * 300);
}
return Math.min(duration, MAX_SCROLL_DURATION);
}
理想情况下,RecyclerView.java类将添加以下行以使其成为可能:
public void smoothScrollBy(int dx, int dy, int vx, int vy, Interpolator interpolator) {
if (mLayout == null) {
Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
+ "Call setLayoutManager with a non-null argument.");
return;
}
if (mLayoutFrozen) {
return;
}
if (!mLayout.canScrollHorizontally()) {
dx = 0;
}
if (!mLayout.canScrollVertically()) {
dy = 0;
}
if (dx != 0 || dy != 0) {
mViewFlinger.smoothScrollBy(dx, dy, vx, vy, interpolator);
}
}
所以到目前为止我还没有办法。