16

Ich habe bereits versucht, das endlose Scrollen für LinearLayoutManager zu implementieren, und es ist erfolgreich und versucht, die LinearLayoutManager-Implementierung nach StaggeredGridLayoutManager zu kopieren, aber es funktioniert nicht.Wie endloses Scrollen mit StaggeredLayoutManager implementieren

Ich möchte nur das erste VisibleItem erhalten.

in LinearLayoutManager:

int firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition(int); 

aber in StaggeredGridLayoutManager ist:

int firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(int[]) 

Wie die firstVisibleItem erhalten mit (int) nicht (int [])?

Gibt es eine gute Herangehensweise/Implementierung?

Vielen Dank im Voraus.

Antwort

-1
int mSpanCount = 2; 

int[] into = new int[mSpanCount]; 

int firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]; 
16

Ich habe es funktioniert:

Sie können in der StaggeredGridLayoutManager eine von zwei Methoden:

  1. findFirstVisibleItemPositions(int[])
  2. findFirstCompletelyVisibleItemPositions(int[])

Pass einen leeren int-Array, wird mit den Positionen initialisiert und verwendet der, der für dich Sinn macht.

private boolean loading = true; 
private int pastVisibleItems, visibleItemCount, totalItemCount; 

mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener({ 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 

     visibleItemCount = mLayoutManager.getChildCount(); 
     totalItemCount = mLayoutManager.getItemCount(); 
     int[] firstVisibleItems = null; 
     firstVisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItems); 
     if(firstVisibleItems != null && firstVisibleItems.length > 0) { 
      pastVisibleItems = firstVisibleItems[0]; 
     } 

     if (loading) { 
      if ((visibleItemCount + pastVisibleItems) >= totalItemCount) { 
       loading = false; 
       Log.d("tag", "LOAD NEXT ITEM"); 
      } 
     } 
    } 
}); 
+0

wirklich für diese Lösung sehr geschätzt. Es funktioniert großartig wie ich will. In der aktualisierten AppCompactLibrary haben sie eine Methode, dies zu tun. Aber aus irgendeinem Grund kann ich die Bibliothek nicht aktualisieren. Also bin ich stecken geblieben. Ihre Antwort gibt mir die richtige Lösung dafür. Danke vielmals. –

0

zu implementieren EndlessRecyclerOnScrollListener ersten EndlessRecyclerOnScrollListener Java-Klasse

import android.support.v7.widget.GridLayoutManager; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.StaggeredGridLayoutManager; 

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener { 
    public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName(); 
    private int scrolledDistance = 0; 
    private boolean controlsVisible = false; 

    private boolean loading = true; // True if we are still waiting for the last set of data to load. 
    private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more. 

    private int pastVisibleItems, visibleItemCount, totalItemCount; 

    private int current_page = 1; 

    private StaggeredGridLayoutManager mStaggeredGridLayoutManager; 

    public EndlessRecyclerOnScrollListener(StaggeredGridLayoutManager staggeredGridLayoutManager) { 
     this.mStaggeredGridLayoutManager = staggeredGridLayoutManager; 

    } 

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

     visibleItemCount = recyclerView.getChildCount(); 
     totalItemCount = mStaggeredGridLayoutManager.getItemCount(); 
     //firstVisibleItem = mStaggeredGridLayoutManager.findFirstVisibleItemPosition(); 
     int[] firstVisibleItems = null; 
     firstVisibleItems = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems); 
     if (firstVisibleItems != null && firstVisibleItems.length > 0) { 
      pastVisibleItems = firstVisibleItems[0]; 
     } 


     if (loading) { 
      if ((visibleItemCount + pastVisibleItems) >= totalItemCount) { 
       loading = false; 
       previousTotal = totalItemCount; 
      } 
     } 
     if (!loading && (totalItemCount - visibleItemCount) 
       <= (pastVisibleItems + visibleThreshold)) { 
      // End has been reached 

      // Do something 
      current_page++; 

      onLoadMore(current_page); 

      loading = true; 
     } 

     if (scrolledDistance > 1 && controlsVisible) { 
      controlsVisible = false; 
      scrolledDistance = 0; 
     } else if (scrolledDistance < -1 && !controlsVisible) { 
      controlsVisible = true; 
      scrolledDistance = 0; 
     } 

     if ((controlsVisible && dy > 0) || (!controlsVisible && dy < 0)) { 
      scrolledDistance += dy; 
     } 
    } 

    public abstract void onLoadMore(int current_page); 

    ; 
} 

Nachdem in Ihre Aktivität oder ein Fragment (in diesem Beispiel des Fragment) verwenden, um den nächsten Code

RecyclerView mRecyclerView; 
StaggeredGridLayoutManager mStaggeredGridLayoutManager; 

private RecyclerView.Adapter adapter; 

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle saveInstanceState) { 

     View v = inflater.inflate(R.layout.notices_layout, container, false); 

     mRecyclerView = (RecyclerView) v.findViewById(R.id.listaNoticias); 
mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(
       2, //number of grid columns 
       GridLayoutManager.VERTICAL); 

//Sets the gap handling strategy for StaggeredGridLayoutManager 
     mStaggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE); 

     mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); 

//initializing our adapter 
adapter = new MyAdapter(list, getContext()); 

//Adding adapter to recyclerview 
mRecyclerView.setAdapter(adapter); 

mRecyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(mStaggeredGridLayoutManager) { 
      @Override 
      public void onLoadMore(int current_page) { 
       // do something... 
       getData(current_page); 
      } 
     }); 

return v; 
} 
5

Es ist meine Implementierung erstellen , sehr nützlich für mich

Verwendung :

private EndlessScrollListener scrollListener = 
     new EndlessScrollListener(new EndlessScrollListener.RefreshList() { 
      @Override public void onRefresh(int pageNumber) { 
       //Here you can execute server connection or anything else to update data and present with Recycler view 
       // Notice: It is sync method 

      } 
     }); 

recyclerView.addOnScrollListener(scrollListener); 

Hier benutzerdefinierte Listener-Klasse:

class EndlessScrollListener extends RecyclerView.OnScrollListener { 
private boolean isLoading; 
private boolean hasMorePages; 
private int pageNumber = 0; 
private RefreshList refreshList; 
private boolean isRefreshing; 
private int pastVisibleItems; 

EndlessScrollListener(RefreshList refreshList) { 
    this.isLoading = false; 
    this.hasMorePages = true; 
    this.refreshList = refreshList; 
} 

@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
    super.onScrolled(recyclerView, dx, dy); 
    StaggeredGridLayoutManager manager = 
      (StaggeredGridLayoutManager) recyclerView.getLayoutManager(); 

    int visibleItemCount = manager.getChildCount(); 
    int totalItemCount = manager.getItemCount(); 
    int[] firstVisibleItems = manager.findFirstVisibleItemPositions(null); 
    if (firstVisibleItems != null && firstVisibleItems.length > 0) { 
     pastVisibleItems = firstVisibleItems[0]; 
    } 

    if ((visibleItemCount + pastVisibleItems) >= totalItemCount && !isLoading) { 
     isLoading = true; 
     if (hasMorePages && !isRefreshing) { 
      isRefreshing = true; 
      new Handler().postDelayed(new Runnable() { 
       @Override public void run() { 
        refreshList.onRefresh(pageNumber); 
       } 
      }, 200); 
     } 
    } else { 
     isLoading = false; 
    } 
} 

public void noMorePages() { 
    this.hasMorePages = false; 
} 

public void notifyMorePages() { 
    isRefreshing = false; 
    pageNumber = pageNumber + 1; 
} 

interface RefreshList { 
    void onRefresh(int pageNumber); 
} 
} 
+0

ist erfrischend ist immer wahr, diese Methode muss öffentlich sein und in "onRefresh" aufgerufen werden –

+0

@PabloCegarra Könnten Sie bitte noch einmal erklären? Ich verstehe nicht, was meinst du? Die Hauptidee des Zuhörers wird dem Entwickler mitgeteilt, wenn der Benutzer das Ende der Liste berührt. Also dieses Ereignis bekommt er in 'onRefresh()'. Oder liege ich falsch? –

+1

Ja funktioniert es wie ein Charme für mich, aber das Beispiel ist verwirrend, weil notifyMorePages nicht öffentlich ist –

Verwandte Themen