webentwicklung-frage-antwort-db.com.de

Android: Steuerung Smooth über die Recycler-Ansicht scrollen

Ich verwende Recyclerview mit CardView. Ich weiß, wie man die Geschwindigkeit in der Listenansicht regelt. Aber nicht für Recyclerview.

Ich suchte viel im gefundenen Klassennamen SmoothScroll . Wie benutzt man das? Ich habe keine Ahnung! Momentan ist das Scrollen von Recyclerview standardmäßig schnell.

UPDATE:

Ich habe Gil Answer mit this zusammengefasst

49
Shabbir Dhangot

Es ist unklar, was Sie meinen, wenn Sie "smoothScroll" sagen. Sie könnten sich auf das automatische "smoothScrollToPosition" beziehen, das automatisch zu einer bestimmten Position scrollt, Sie könnten über manuelles Scrollen und Sie könnten über Schleudern sprechen. Im Interesse des Wohlstands werde ich jetzt versuchen, alle diese Fragen zu beantworten.

1. Automatisches ruckelfreies Scrollen

In Ihrem Layout-Manager müssen Sie die Methode smoothScrollToPosition implementieren:

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
    {
        // A good idea would be to create this instance in some initialization method, and just set the target position in this method.
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(getContext())
        {
            @Override
            public PointF computeScrollVectorForPosition(int targetPosition)
            {
                int yDelta = calculateCurrentDistanceToPosition(targetPosition);
                return new PointF(0, yDelta);
            }

            // This is the important method. This code will return the amount of time it takes to scroll 1 pixel.
            // This code will request X milliseconds for every Y DP units.
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
            {
                return X / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Y, displayMetrics);
            }

        };
        smoothScroller.setTargetPosition(position);

        startSmoothScroll(smoothScroller);
    }

In diesem Beispiel verwende ich eine Hilfsmethode mit dem Namen "calculatorCurrentDistanceToPosition". Dies kann etwas schwierig sein, da Sie die aktuelle Bildlaufposition verfolgen und die Bildlaufposition für eine bestimmte y-Position berechnen müssen. Sie finden ein Beispiel, wie Sie die Schriftrolle des Recyclers verfolgen können. Y hier .

Die Berechnung des Bildlaufs y einer bestimmten Position hängt wirklich davon ab, was Ihr Recycler anzeigt. Angenommen, alle Ihre Artikel haben dieselbe Höhe, können Sie dies berechnen, indem Sie die folgende Berechnung durchführen:

targetScrollY = targetPosition * itemHeight

Um dann die Entfernung zu berechnen, die Sie scrollen müssen, subtrahieren Sie einfach die aktuelle Schriftrolle y mit der Zielschriftrolle y:

private int calculateCurrentDistanceToPosition(int targetPosition) {
    int targetScrollY = targetPosition * itemHeight;
    return targetScrollY - currentScrollY;
}

2. Manuelles Scrollen verlangsamen

Auch dieses Mal müssen Sie Ihren Layout-Manager bearbeiten - die scrollVerticallyBy -Methode:

    @Override
    public int scrollVerticallyBy(int delta, Recycler recycler, State state)
    {
       // write your limiting logic here to prevent the delta from exceeding the limits of your list.

       int prevDelta = delta;
       if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = (int)(delta > 0 ? Math.max(delta * MANUAL_SCROLL_SLOW_RATIO, 1) : Math.min(delta * MANUAL_SCROLL_SLOW_RATIO, -1));  

       // MANUAL_SCROLL_SLOW_RATIO is between 0 (no manual scrolling) to 1 (normal speed) or more (faster speed).
       // write your scrolling logic code here whereby you move each view by the given delta

        if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = prevDelta;

        return delta;
    }

Edit: In der obigen Methode rufe ich "getScrollState()" auf. Dies ist eine Methode von RecyclerView. In dieser Implementierung ist mein benutzerdefiniertes LayoutManager eine verschachtelte Klasse meines benutzerdefinierten RecyclerView. Wenn dies bei Ihnen nicht funktioniert, können Sie versuchen, den Bildlaufstatus über ein Schnittstellenmuster abzurufen.

3. Schleudergeschwindigkeit verringern

Hier möchten Sie die Schleudergeschwindigkeit verringern. Sie müssen die fling -Methode in Ihrer RecyclerView-Unterklasse überschreiben:

@Override
public boolean fling(int velocityX, int velocityY)
{
     velocityY *= FLING_SCALE_DOWN_FACTOR; // (between 0 for no fling, and 1 for normal fling, or more for faster fling).

     return super.fling(velocityX, velocityY);
}

Es ist schwierig für mich, eine maßgeschneiderte Lösung bereitzustellen, da Sie keinen Code veröffentlicht oder viele Informationen zu Ihrem Setup bereitgestellt haben, aber ich hoffe, dass dies die meisten Grundlagen abdeckt und Ihnen hilft, die beste Lösung für Sie zu finden.

100
Gil Moshayof

Ich vereinfache nur Beantworten Sie, wie man es verwendet, um einen glatten Bildlauf zu steuern.

Klasse erstellen

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.util.AttributeSet;

public class CustomRecyclerView extends RecyclerView {

    Context context;

    public CustomRecyclerView(Context context) {
        super(context);
        this.context = context;
    }

    public CustomRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean fling(int velocityX, int velocityY) {

        velocityY *= 0.7;
        // velocityX *= 0.7; for Horizontal recycler view. comment velocityY line not require for Horizontal Mode.

        return super.fling(velocityX, velocityY);
    }

}

Stellen Sie die Geschwindigkeit durch Ersetzen von .7 auf Ihren Wert ein.

Verwenden Sie nun diese Klasse in Ihrem XML wie folgt.

<<yourpackage>.CustomRecyclerView
    Android:id="@+id/my_recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:scrollbars="vertical" />

Lesen Sie RecyclerView in Java like.

CustomRecyclerView mRecyclerView;
mRecyclerView = (CustomRecyclerView) findViewById(R.id.my_recycler_view);
32
Shabbir Dhangot

Implementieren Sie einfach smoothScrollToPosition () Ihres LinearLayoutManagers:

LinearLayoutManager layoutManager = new LinearLayoutManager(this) {

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(this) {

            private static final float SPEED = 300f;// Change this value (default=25f)

            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return SPEED / displayMetrics.densityDpi;
            }

        };
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

};
27
Blunderer