2016-03-07 11 views
8

Ich verwende StaggeredGridLayoutManager für meine Bildergalerie. Ich habe setReverseLayout(true) eingestellt, so dass Bilder von unten gestapelt werden.Android: StaggeredGridLayoutManager blättern Sie nach oben beim Initialisieren

Das Problem, mit dem ich konfrontiert bin, ist, dass bei der Initialisierung der App die Scroll-Punkte am unteren Rand der Galerie. Ich möchte, dass die Bildlaufleiste oben in der Galerie angezeigt wird, wenn der Benutzer die App zum ersten Mal startet.

Ich habe versucht, scrollToPosition (den folgenden Codeausschnitt) verwenden, aber dann die Scroll endet irgendwo in der Mitte der Galerie oben, wahrscheinlich, weil die Bilder nicht richtig zum Zeitpunkt des Aufrufs scrollToPosition geladen.

mLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL); 
    mLayoutManager.setReverseLayout(true); 

mRecyclerView.setLayoutManager(mLayoutManager); 
mImageList = ((MainActivity)getActivity()).getImages(); 
adapter = new ImageAdapter(getActivity(),mImageList); 
mRecyclerView.setAdapter(adapter); 
mRecyclerView.scrollToPosition(mImageList.size()-1); 

Gibt es einen richtigen Weg, um die Schriftrolle oben anstatt unten zu zeigen?

Antwort

2

Ich löste ähnliches Problem vor, und hier ist Methode:

mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() { 
        @SuppressWarnings("deprecation") 
        @Override 
        public void onGlobalLayout() { 
         ViewTreeObserver observer = mRecyclerView.getViewTreeObserver(); 
         scrollRecyclerViewToTop(); 
         if (!observer.isAlive()) { 
          return; 
         } 
         if (mScrolledByUser) { 
          if (hasJellyBeanApi()) { 
           observer.removeOnGlobalLayoutListener(this); 
          } else { 
           observer.removeGlobalOnLayoutListener(this); 
          } 
         } 
        } 
       }); 

Und:

Und:

private void scrollRecyclerViewToTop() { 
    mRecyclerView.scrollToPosition(0); 
    mRecyclerView.scrollBy(0, Integer.MIN_VALUE); 
} 

Die Bedeutung ist einfach: Lassen Sie RecyclerView immer Scrollen Sie nach oben, bis Sie u Ser berührt es. Hoffe, das kann dir helfen.

+0

es funktioniert, wenn ich den Bildschirm berühre, aber nichts zeigt sich, wenn ich nicht berühre. Ich möchte es standardmäßig scrollen, dass der Benutzer nicht berühren muss. Dies ist die nächste Antwort, also werde ich Ihnen eine Prämie zuteilen. Übrigens funktioniert meine Antwort so, wie ich will. – uguboz

1

versuchen, die erste sichtbare Position zu finden, durch den Aufruf findFirstCompletelyVisibleItemPositions

oder findFirstVisibleItemPositions

die Ihre Recycler Ansicht scrollToPosition mit der aus dem vorherigen Verfahren erhaltenen Position nennen (s)

+0

Das wird das Problem nicht vollständig lösen. Der erste sichtbare Gegenstand ist nicht immer der letzte Gegenstand. So kann ich am Ende zu verschiedenen Positionen auf verschiedenen Läufen scrollen. – Neo

0

Versuchen Sie sich mit scrollToPositionWithOffset() Funktion StaggeredGridLayoutManager stattdessen. Ich fand es zuverlässiger als scrollToPosition. Stellen Sie außerdem sicher, dass Sie diese Funktion innerhalb von Handler().post() ausführen. Dadurch wird Runnable zur Nachrichtenwarteschlange hinzugefügt. Es wird ausgeführt, sobald der UI-Thread frei ist.

new Handler().post(new Runnable() { 
      @Override 
      public void run() { 
       staggeredGridLayoutManager.scrollToPositionWithOffset(mImageList.size() - 1, 0); 
      } 
     }); 
+0

Leider hat es nicht für mich funktioniert. Thansk für die Antwort – uguboz

1

I verwendet scrolltoposition innen dataobserver und jetzt funktioniert es gut ..

Wenn die recyclerview Lasten, Gegenstände auf den Code unten sichtbar sind:

rcAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { 
      @Override 
      public void onItemRangeInserted(int positionStart, int itemCount) { 
       super.onItemRangeInserted(positionStart, itemCount); 
       int count = rcAdapter.getItemCount(); 
       mRecyclerView.scrollToPosition(itemCount-1); 

      } 
     }); 

nach unten scrollen Verwenden Sie für neu hinzugefügte Elemente wie in der Chat-Ansicht den folgenden Code.

 rcAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { 
        @Override 
        public void onItemRangeInserted(int positionStart, int itemCount) { 
         super.onItemRangeInserted(positionStart, itemCount); 
         int count = rcAdapter.getItemCount(); 
         int lastVisiblePositions[] = new int[2]; //for 2 columns 
         int lastVisiblePosition = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(lastVisiblePositions)[0]; 
         // If the recycler view is initially being loaded or the user is at the bottom of the list, scroll 
         // to the bottom of the list to show the newly added message. 
         if (lastVisiblePosition == -1 || 
          (positionStart >= (count- 1) && lastVisiblePosition == (positionStart - 1))) { 
          mRecyclerView.scrollToPosition(positionStart); 
         } 

        } 
       }); 
+0

Sieht interessant aus. – Neo

0

Dieser Code kann Ihnen helfen, ich diesen Link in Code auch

https://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView

Jeder AdapterView (wie Listview und Gridview) hat die Unterstützung für Bindung an die OnScrollListener Ereignisse verwendet, die, wann immer ausgelöst werden a Der Benutzer scrollt durch die Sammlung.Mit diesem System können wir einen grundlegenden EndlessScrollListener definieren, die die meisten Anwendungsfälle von unterstützt unsere eigene Klasse erstellen, die OnScrollListener erweitert:

public abstract class EndlessScrollListener implements AbsListView.OnScrollListener { 
    // The minimum number of items to have below your current scroll position 
    // before loading more. 
    private int visibleThreshold = 5; 
    // The current offset index of data you have loaded 
    private int currentPage = 0; 
    // The total number of items in the dataset after the last load 
    private int previousTotalItemCount = 0; 
    // True if we are still waiting for the last set of data to load. 
    private boolean loading = true; 
    // Sets the starting page index 
    private int startingPageIndex = 0; 

    public EndlessScrollListener() { 
    } 

    public EndlessScrollListener(int visibleThreshold) { 
     this.visibleThreshold = visibleThreshold; 
    } 

    public EndlessScrollListener(int visibleThreshold, int startPage) { 
     this.visibleThreshold = visibleThreshold; 
     this.startingPageIndex = startPage; 
     this.currentPage = startPage; 
    } 

    // This happens many times a second during a scroll, so be wary of the code you place here. 
    // We are given a few useful parameters to help us work out if we need to load some more data, 
    // but first we check if we are waiting for the previous load to finish. 
    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 
    { 
     // If the total item count is zero and the previous isn't, assume the 
     // list is invalidated and should be reset back to initial state 
     if (totalItemCount < previousTotalItemCount) { 
      this.currentPage = this.startingPageIndex; 
      this.previousTotalItemCount = totalItemCount; 
      if (totalItemCount == 0) { this.loading = true; } 
     } 
     // If it's still loading, we check to see if the dataset count has 
     // changed, if so we conclude it has finished loading and update the current page 
     // number and total item count. 
     if (loading && (totalItemCount > previousTotalItemCount)) { 
      loading = false; 
      previousTotalItemCount = totalItemCount; 
      currentPage++; 
     } 

     // If it isn't currently loading, we check to see if we have breached 
     // the visibleThreshold and need to reload more data. 
     // If we do need to reload some more data, we execute onLoadMore to fetch the data. 
     if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount) { 
     loading = onLoadMore(currentPage + 1, totalItemCount); 
     } 
    } 

    // Defines the process for actually loading more data based on page 
    // Returns true if more data is being loaded; returns false if there is no more data to load. 
    public abstract boolean onLoadMore(int page, int totalItemsCount); 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
     // Don't take any action on changed 
    } 
    } 
Verwandte Themen