2015-07-05 6 views
39

Auf einem RecyclerView, ich bin durch mit an die Spitze eines ausgewählten Elements plötzlich in der Lage zu blättern: RecyclerView - Wie glättet man den Bildlauf an einer bestimmten Stelle nach oben?

((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(position, 0); 

jedoch

Dieses abrupt das Element in die obere Position bewegt. Ich möchte an die Spitze eines Artikels glatt verschieben.

Ich habe auch versucht:

recyclerView.smoothScrollToPosition(position); 

aber es funktioniert nicht gut, da es nicht das Objekt an die Position nach oben ausgewählt bewegt. Es scrollt lediglich die Liste, bis das Element an der Position sichtbar ist.

Antwort

51

RecyclerView soll erweiterbar sein, so gibt es keine Notwendigkeit, die LayoutManager (als droidev suggested), Unterklasse nur das Scrollen auszuführen. Statt

, erstellen Sie einfach eine SmoothScroller mit der Präferenz SNAP_TO_START:

RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) { 
    @Override protected int getVerticalSnapPreference() { 
    return LinearSmoothScroller.SNAP_TO_START; 
    } 
}; 

Nun stellen Sie die Position, die Sie blättern möchten:

smoothScroller.setTargetPosition(position); 

und dass SmoothScroller an den Layoutmanager übergeben:

layoutManager.startSmoothScroll(smoothScroller); 
+1

Danke für diese kürzere Lösung. Nur noch zwei Dinge, die ich in meiner Implementierung berücksichtigen musste: Da ich eine horizontal scrollende Ansicht habe, musste ich 'protected int setzen getHorizontalSnapPreference() {return LinearSmoothScroller.SNAP_TO_START; } '. Außerdem musste ich die abstrakte Methode 'public PointF computeScrollVectorForPosition (int targetPosition) implementieren {return layoutManager.computeScrollVectorForPosition (targetPosition); } '. – AustrianDude

+0

@AustrianDude 'computeScrollVectorForPosition' ist nicht abstrakt. Außerdem wird standardmäßig 'layoutManager.computeScrollVectorForPosition' zurückgegeben. –

+0

Okay. Ich benutze leider die v7 Support-Bibliothek 23.4.0. Dies muss in einer späteren Version geändert worden sein. – AustrianDude

78

hierfür müssen Sie Layout

public class LinearLayoutManagerWithSmoothScroller extends LinearLayoutManager { 

    public LinearLayoutManagerWithSmoothScroller(Context context) { 
     super(context, VERTICAL, false); 
    } 

    public LinearLayoutManagerWithSmoothScroller(Context context, int orientation, boolean reverseLayout) { 
     super(context, orientation, reverseLayout); 
    } 

    @Override 
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, 
             int position) { 
     RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()); 
     smoothScroller.setTargetPosition(position); 
     startSmoothScroll(smoothScroller); 
    } 

    private class TopSnappedSmoothScroller extends LinearSmoothScroller { 
     public TopSnappedSmoothScroller(Context context) { 
      super(context); 

     } 

     @Override 
     public PointF computeScrollVectorForPosition(int targetPosition) { 
      return LinearLayoutManagerWithSmoothScroller.this 
        .computeScrollVectorForPosition(targetPosition); 
     } 

     @Override 
     protected int getVerticalSnapPreference() { 
      return SNAP_TO_START; 
     } 
    } 
} 

Verwendung dieses für Ihren RecyclerView und rufen smoothScrollToPosition eine benutzerdefinierte erstellen.

Beispiel:

recyclerView.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(context)); 
recyclerView.smoothScrollToPosition(position); 

dies oben auf dem RecyclerView Artikel der angegebenen Position bewegen wird.

hoffe das hilft.

+0

Ich hatte Probleme, den vorgeschlagenen LayoutManager zu implementieren. Diese Antwort hier funktioniert viel einfacher für mich: http://stackoverflow.com/questions/28025425/android-recyclerview-smooth-scroll-to-view-thats-animating-their-height – arberg

+3

Nur nützliche Antwort nach Stunden des Schmerzes, dies funktioniert wie geplant! – wblaschko

+2

Die SNAP_TO_START machen den Trick! Tks! – DragonT

1

Der einfachste Weg, den ich habe und eine RecyclerView zu blättern ist wie folgt:

// Define the Index we wish to scroll to. 
final int lIndex = 0; 
// Assign the RecyclerView's LayoutManager. 
this.getRecyclerView().setLayoutManager(this.getLinearLayoutManager()); 
// Scroll the RecyclerView to the Index. 
this.getLinearLayoutManager().smoothScrollToPosition(this.getRecyclerView(), new RecyclerView.State(), lIndex); 
0

Wir können versuchen, wie diese

recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,new RecyclerView.State(), recyclerView.getAdapter().getItemCount()); 
0

Wahrscheinlich @droidev Ansatz der richtige ist, aber ich will nur etwas ein wenig anders veröffentlichen, die macht im Grunde den gleichen Job und benötigt keine Erweiterung des LayoutManagers.

Ein HINWEIS hier - das wird gut funktionieren, wenn Ihr Artikel (derjenige, den Sie oben auf der Liste scrollen möchten) auf dem Bildschirm sichtbar ist und Sie nur nach oben automatisch scrollen möchten.Es ist nützlich, wenn das letzte Element in der Liste eine Aktion hat, die neue Objekte in derselben Liste hinzufügt und Sie den Benutzer auf die neu hinzugefügte Elemente konzentrieren:

int recyclerViewTop = recyclerView.getTop(); 
int positionTop = recyclerView.findViewHolderForAdapterPosition(positionToScroll) != null ? recyclerView.findViewHolderForAdapterPosition(positionToScroll).itemView.getTop() : 200; 
final int calcOffset = positionTop - recyclerViewTop; 
//then the actual scroll is gonna happen with (x offset = 0) and (y offset = calcOffset) 
recyclerView.scrollBy(0, offset); 

Die Idee ist einfach: 1. Wir müssen die oberste Koordinate des RecyclerView-Elements ermitteln. 2. Wir müssen die oberste Koordinate des Ansichtselements erhalten, das wir nach oben scrollen möchten; 3. Am Ende mit dem Offset berechnet wir gerade Beispiel hart codierte Integer-Wert tun müssen, ist

recyclerView.scrollBy(0, offset); 

200, die Sie, wenn der viewholder Artikel existiert nicht verwenden können, denn das ist möglich, auch ist.

Verwandte Themen