Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Scroller fling to fixed position

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);
        }
    }
}
like image 537
Maria Neumayer Avatar asked Nov 04 '22 01:11

Maria Neumayer


1 Answers

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));

like image 79
Maria Neumayer Avatar answered Nov 11 '22 12:11

Maria Neumayer