5

I'm trying to use a Scroller to fling to a fixed position. My problem is: it ends up in the correct position, but it's either just running once and setting the end position immediately or scrolls very slowly first and then jumps to the end.

EDIT: the problem seems to be that a) my velocity is zero sometimes (that's a problem somewhere else :)) and that I have to extend the duration using scroller.extendDuration(). However I am unsure about what the duration should be. I can find no information about what a certain velocity actually means. Is it pixels per second?

Here's my code:

private class Flinger implements Runnable {

    private final Scroller scroller;

    private int lastX = 0;

    public Flinger() {
        scroller = new Scroller(getContext());
    }

    void startFling(int initialVelocity, int offsetX) {
        Log.d("test", "finalX = " + offsetX);
        if (offsetX > 0) {
            scroller.fling(0, 0, initialVelocity, 0, 0, Integer.MAX_VALUE, 0, 0);
            scroller.setFinalX(offsetX);
            lastX = 0;
        } else {
            scroller.fling(getWidth(), 0, initialVelocity, 0, 0, Integer.MAX_VALUE, 0, 0);
            scroller.setFinalX(getWidth() + offsetX);
            lastX = getWidth();
        }
        post(this);
    }

    @Override
    public void run() {
        if (scroller.isFinished()) {
            Log.d("test", "scroller finished");
            return;
        }

        boolean more = scroller.computeScrollOffset();
        int x = scroller.getCurrX();
        int diff = lastX - x;
        Log.d("test", "isFlinging, x=" + x + ", diff=" + diff + ", leftOffset=" + getLeftOffset() + ", isDone=" + !more);
        if (diff != 0) {
            setLeftOffset(getLeftOffset() - diff);
            lastX = x;
        }

        if (more) {
            post(this);
        }
    }
}
Maria Neumayer
  • 3,337
  • 3
  • 27
  • 44
  • How you are calculating the velocity, and also are you doing this scrolling functionality on user interaction, like touch move – Triode Apr 12 '12 at 11:50
  • How you are calculating the velocity, and also are you doing this scrolling functionality on user interaction, like touch move if that is the case then why you cant use some thing like this final int delta = newX - getScrollX(); mScroller.startScroll(getScrollX(), 0, delta, 0,Math.abs(delta)); newX is the current mouse up position. And also you can use velocity tracker to check the touch move velocity. – Triode Apr 12 '12 at 12:00
  • Yes I'm using a VelocityTracker, but I've figured out what the problem was (see answer below). Thanks! – Maria Neumayer Apr 12 '12 at 12:51

1 Answers1

2

Okay I got it. Indeed I had to extend my duration (however the documentation is a bit misleading - it's not the value that's added to the current computed duration, it's the actual new duration).

After reading a bit more documentation I've realized that the velocity needed is indeed pixels per seconds and I've actually defined the VelocityTracker to use this unit.

So this is the missing line:

scroller.extendDuration((int) (Math.abs(offsetX) / (float) Math.max(1000, Math.abs(initialVelocity)) * 1000));

Maria Neumayer
  • 3,337
  • 3
  • 27
  • 44