2015-02-20 18 views
14

Um Endlos-Scroll-Muster zu implementieren, um die RecyclerView ich eine Klasse wieWarum RecyclerView.OnScrollListener ist keine Schnittstelle, sondern eine abstrakte Klasse?

public class EndlessScrollAdapter<VH extends ViewHolder> 
     extends RecyclerView.Adapter<VH> implements RecyclerView.OnScrollListener { 
} 

erstellen möchten Da EndlessScrollAdapter sollte für beide der Daten und blättern Event-Handling verantwortlich sein, dann ist dies der bequemste Weg, es zu implementieren.

Aber weil in recyclerview-v7-21.0.3, OnScrollListener wie diese

erklärt
/** 
* An OnScrollListener can be set on a RecyclerView to receive messages 
* when a scrolling event has occurred on that RecyclerView. 
* 
* @see RecyclerView#setOnScrollListener(OnScrollListener) 
*/ 
abstract static public class OnScrollListener { 
    /** 
    * Callback method to be invoked when RecyclerView's scroll state changes. 
    * 
    * @param recyclerView The RecyclerView whose scroll state has changed. 
    * @param newState  The updated scroll state. One of {@link #SCROLL_STATE_IDLE}, 
    *      {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}. 
    */ 
    public void onScrollStateChanged(RecyclerView recyclerView, int newState){} 

    /** 
    * Callback method to be invoked when the RecyclerView has been scrolled. This will be 
    * called after the scroll has completed. 
    * 
    * @param recyclerView The RecyclerView which scrolled. 
    * @param dx The amount of horizontal scroll. 
    * @param dy The amount of vertical scroll. 
    */ 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy){} 
} 

kann ich nicht EndlessScrollAdapterOnScrollListener implementieren machen.

Also, wie der Titel sagt, gibt es einen guten Grund für OnScrollListener, eine Klasse und nicht eine Schnittstelle zu sein? Weil ich denke, dass es eine Schnittstelle sein sollte.

Antwort

13

Ich hatte die gleiche Frage, und es ist auf jeden Fall so gestaltet, wie in diesem Fehlerbericht beantwortet:

https://code.google.com/p/android/issues/detail?id=79283

Abstrakte Klassen ermöglichen Frameworks das Hinzufügen neuer Methoden, ohne bestehende Implementierungen zu unterbrechen.

den Scroll Zusammenhang Rückrufe

https://android.googlesource.com/platform/frameworks/support/+/cef7b49%5E!/

Diese Änderung fügt RecyclerView als ersten Parameter:

Auch der Unterschied, dass es eingeführt wird, kann hier gefunden werden.

Es gibt auch einen Fehler, bei dem Scroll-Callback mit dem beabsichtigten Scroll Betrag anstelle des tatsächlichen Scroll-Betrags aufgerufen wurde.

Ich änderte es auch, um eine abstrakte Klasse anstelle einer Schnittstelle zu sein, um zukünftige Änderungen zu erleichtern.

Nicht sicher, dass ich der Änderung persönlich zustimme, aber dort ya gehen.

+5

sprechen über schlechte Design-Entscheidungen ... – marmor

+0

Der Grund auf, um den Hörer in Ihrem metdod

... recyclerView.addOnScrollListener(new ScrollListener()); ... 

und schaffen eine innere Listener-Klasse zu vermeiden erwähnt Das Commit ist "Ich habe es auch geändert, um eine abstrakte Klasse anstelle einer Schnittstelle zu sein, um zukünftige Änderungen einfacher zu machen." Aber man sollte keine Änderungen vornehmen, die auf der Zukunft basieren, wie in diesem Fall, diese Klasse wird sich nie ändern und es könnte sicherlich eine Schnittstelle für den Rest des Lebens sein. Es ist zwei Jahre her und es ist immer noch dasselbe. – LeonardoSibela

6

Ich kann nicht EndlessScrollAdapter implementieren OnScrollListener.

Es ist wahr, aber man kann eine eigene Klasse, die extends RecyclerView.OnScrollListener (ein konkretes Beispiel von RecyclerView.OnScrollListener) hat. ZB

private class MyScrollListener extends RecyclerView.OnScrollListener { 
    // abstract methods implemenations 
} 

und das, was Sie brauchen, ist nur

mRecyclerView.addOnScrollListener(new MySCrollListener()); 
0
yourRecyclerview.setOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
      super.onScrollStateChanged(recyclerView, newState); 
     } 

     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 
     } 
    }); 
1

die Idee

private class ScrollListener extends RecyclerView.OnScrollListener { 
    @Override 
    public void onScrollStateChanged(RecyclerView recyclerView, int newState){ 
     // your code there 
    } 

    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
     // your code there 
    } 
} 
+0

Obwohl der 'setOnscrollListener' direkt auf einer Instanz der Recycler-Ansicht aufgerufen wird, ist sie veraltet, so dass sie auf diese Weise funktioniert wie ein Zauber. Vielen Dank! –