2016-03-07 49 views
8

Używam galerii . Ustawiłem setReverseLayout(true), aby obrazy były układane od dołu.Android: StaggeredGridLayoutManager przewiń do góry podczas inicjowania

Problem, przed którym stoję, polega na tym, że podczas inicjowania aplikacji punkty przewijania znajdują się u dołu galerii. Chciałbym, aby przewój znalazł się na górze galerii, gdy użytkownik po raz pierwszy uruchomi aplikację.

Próbowałem użyć scrollToPosition (poniższy fragment kodu), ale przewijanie kończy się gdzieś pośrodku galerii, prawdopodobnie dlatego, że obrazy nie zostały załadowane poprawnie w momencie wywoływania 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); 

Czy istnieje właściwy sposób wskazywania przewijania u góry, a nie u dołu?

Odpowiedz

2

I rozwiązać podobny problem przed i tutaj jest metoda:

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

I:

I:

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

Sens jest proste: niech RecyclerView zawsze przewijaj do góry, aż u ser dotyka tego. Mam nadzieję, że to może ci pomóc.

+0

działa po dotknięciu ekranu, ale nic nie pokazuje się, gdy nie dotykam. Chcę go domyślnie przewinąć, a użytkownik nie musi dotykać. To jest najbliższa odpowiedź, więc przyznam nagrodę za ciebie. btw moja odpowiedź działa tak, jak chcę. – uguboz

1

próby znalezienia pierwszego widocznym miejscu poprzez wywołanie findFirstCompletelyVisibleItemPositions

lub findFirstVisibleItemPositions

nazywają swój pogląd recykler scrollToPosition z położenia uzyskanego z poprzedniej metodzie (-ach)

+0

To nie rozwiąże problemu całkowicie. Pierwsza widoczna pozycja nie zawsze będzie ostatnią pozycją. Więc mogę skończyć przewijanie do różnych pozycji w różnych przebiegach. – Neo

0

Spróbuj użyć scrollToPositionWithOffset() funkcję StaggeredGridLayoutManager zamiast tego. Stwierdziłem, że jest bardziej niezawodny niż scrollToPosition. Upewnij się także, że wykonujesz tę funkcję wewnątrz Handler().post(). Spowoduje to dodanie Runnable do kolejki komunikatów. Uruchomi się, gdy wątek interfejsu użytkownika jest wolny.

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

Niestety to nie działa dla mnie. Thansk za odpowiedź – uguboz

1

użyłem scrolltoposition wewnątrz dataobserver i teraz działa dobrze ..

Po załadowaniu recyclerview, elementy na górze są widoczne z kodem poniżej:

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

      } 
     }); 

aby przewinąć do dołu w przypadku nowo dodanych elementów, jak w widoku czatu, użyj poniższego kodu.

 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

Wygląda interesująco. – Neo

0

Kod ten może pomóc, użyłem również ten link w kodzie

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

Każdy AdapterView (takich jak ListView i GridView) posiada wsparcie dla wiązanie do wydarzeń OnScrollListener które są wywoływane, gdy a Użytkownik przewija kolekcję.Korzystanie z tego systemu, możemy zdefiniować podstawową EndlessScrollListener który obsługuje większość przypadków użycia przez stworzenie własnej klasy, która rozciąga 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 
    } 
    }