Recyclerview使用scrollBy方法控制滚动速度

时间:2018-07-11 09:13:18

标签: android android-recyclerview

亲爱的我已经设法通过自定义线性布局管理器使用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)
    }


}    

1 个答案:

答案 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);
        }
    }

所以到目前为止我还没有办法。