2016-03-07 18 views
8

Sto usando StaggeredGridLayoutManager per la mia galleria di immagini. Ho impostato setReverseLayout(true), in modo che le immagini vengano impilate dal basso.Android: StaggeredGridLayoutManager scorre verso l'alto durante l'inizializzazione

Il problema che sto affrontando è che durante l'inizializzazione dell'app, i punti di scorrimento nella parte inferiore della galleria. Vorrei che la pergamena fosse nella parte superiore della galleria quando l'utente avvia per la prima volta l'app.

Ho provato a utilizzare scrollToPosition (il seguente snippet di codice) ma poi lo scorrimento finisce da qualche parte nel mezzo della galleria, probabilmente perché le immagini non sono state caricate correttamente al momento della chiamata scrollToPosition.

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); 

C'è un modo corretto di puntare lo scroll in alto, piuttosto che in basso?

risposta

2

ho risolto problema simile prima e qui è il metodo:

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); 
          } 
         } 
        } 
       }); 

E:

E:

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

Il significato è semplice: lasciare che RecyclerView sempre scorrere verso l'alto fino a u ser lo tocca. Spero che questo possa aiutarti.

+0

funziona quando tocco lo schermo ma non compare nulla se non tocco. Voglio scorrerlo di default che l'utente non ha bisogno di toccare. Questa è la risposta più vicina quindi assegnerò la taglia per te. btw la mia risposta funziona come voglio. – uguboz

1

provare a trovare la prima posizione visibile chiamando findFirstCompletelyVisibleItemPositions

o findFirstVisibleItemPositions

l'chiamare la vista riciclatore ScrollToPosition con la posizione ottenuta dal metodo precedente (s)

+0

Questo non risolverà completamente il problema. Il primo oggetto visibile non sarà sempre l'ultimo oggetto. Quindi potrei finire per scorrere a posizioni diverse su piste diverse. – Neo

0

Provate ad usare scrollToPositionWithOffset() funzione StaggeredGridLayoutManager invece. L'ho trovato più affidabile di scrollToPosition. Assicurati inoltre di eseguire questa funzione all'interno di Handler().post(). Ciò causerà l'aggiunta di Runnable alla coda dei messaggi. Verrà eseguito una volta che il thread dell'interfaccia utente è libero.

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

Sfortunatamente non ha funzionato per me. Grazie per la risposta – uguboz

1

ho usato ScrollToPosition all'interno dataobserver e ora funziona benissimo ..

Quando i carichi recyclerview, articoli sulla parte superiore sono visibili con il codice qui sotto:

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); 

      } 
     }); 

per scorrere verso il basso per gli elementi aggiunti di recente come nella vista della chat, utilizzare il codice riportato di seguito.

 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

Sembra interessante. – Neo

0

Questo codice può aiutare, ho usato anche questo link nel codice

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

Ogni AdapterView (come ListView e GridView) ha il supporto per legame con gli eventi OnScrollListener che vengono attivati ​​ogni volta a L'utente scorre la collezione.Utilizzando questo sistema, possiamo definire un EndlessScrollListener di base che supporta la maggior parte dei casi d'uso da creare la nostra classe che estende OnScrollListener:

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 
    } 
    } 
Problemi correlati