2016-03-07 27 views
8

Tôi đang sử dụng StaggeredGridLayoutManager cho thư viện hình ảnh của mình. Tôi đã đặt setReverseLayout(true), để hình ảnh được xếp chồng lên nhau từ dưới cùng.Android: StaggeredGridLayoutManager di chuyển lên trên cùng trong khi khởi tạo

Vấn đề tôi đang gặp phải là lúc khởi tạo ứng dụng, các điểm cuộn ở cuối thư viện. Tôi muốn cuộn nằm ở đầu thư viện khi người dùng khởi động ứng dụng lần đầu tiên.

Tôi đã thử sử dụng scrollToPosition (đoạn mã sau) nhưng sau đó cuộn lên ở đâu đó ở giữa thư viện, có thể do hình ảnh chưa được tải đúng vào thời điểm gọi 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ó cách nào phù hợp để chỉ cuộn ở trên cùng chứ không phải ở dưới cùng?

Trả lời

2

tôi giải quyết vấn đề tương tự trước và đây là phương pháp:

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

Và:

Và:

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

Ý nghĩa là dễ dàng: hãy RecyclerView luôn cuộn lên trên cho đến khi bạn ser chạm vào nó. Hy vọng điều này có thể giúp bạn.

+0

nó hoạt động khi tôi chạm vào màn hình nhưng không có gì hiển thị nếu tôi không chạm vào. Tôi muốn di chuyển nó theo mặc định là người dùng không cần phải chạm vào. Đây là câu trả lời gần nhất vì vậy tôi sẽ trao tiền thưởng cho bạn. btw câu trả lời của tôi hoạt động như tôi muốn. – uguboz

1

thử tìm vị trí có thể nhìn thấy đầu tiên bằng cách gọi findFirstCompletelyVisibleItemPositions

hoặc findFirstVisibleItemPositions

các gọi xem tái chế của bạn scrollToPosition với vị trí thu được từ các phương pháp trước đó (s)

+0

Điều đó sẽ không giải quyết được vấn đề hoàn toàn. Mục hiển thị đầu tiên sẽ không phải lúc nào cũng là mục cuối cùng. Vì vậy, tôi có thể sẽ di chuyển đến các vị trí khác nhau trên các lần chạy khác nhau. – Neo

0

Hãy thử sử dụng scrollToPositionWithOffset() chức năng StaggeredGridLayoutManager thay thế. Tôi thấy nó đáng tin cậy hơn scrollToPosition. Ngoài ra hãy chắc chắn rằng bạn thực hiện chức năng này bên trong Handler().post(). Điều này sẽ làm cho Runnable được thêm vào hàng đợi tin nhắn. Nó sẽ chạy khi thread UI miễn phí.

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

Thật không may nó không làm việc cho tôi. Thansk cho câu trả lời – uguboz

1

tôi đã sử dụng scrolltoposition bên dataobserver và bây giờ nó hoạt động tốt ..

Khi tải recyclerview, các mục trên đỉnh có thể nhìn thấy với mã dưới đây:

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

      } 
     }); 

để di chuyển đến phía dưới đối với các mục mới được thêm như trong chế độ xem trò chuyện, hãy sử dụng mã bên dưới.

 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

Trông thú vị. – Neo

0

Mã này có thể giúp bạn, tôi cũng sử dụng liên kết này trong mã

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

Mỗi AdapterView (như ListView và GridView) đã hỗ trợ cho liên kết với các sự kiện OnScrollListener được kích hoạt bất cứ khi nào a Người dùng cuộn qua bộ sưu tập.Sử dụng hệ thống này, chúng ta có thể xác định một EndlessScrollListener cơ bản, hỗ trợ hầu hết các trường hợp sử dụng bằng cách tạo lớp riêng của chúng tôi kéo dài 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 
    } 
    } 
Các vấn đề liên quan