2016-03-07 308 views
8

我使用StaggeredGridLayoutManager作为我的图片库。我已设置setReverseLayout(true),以便图像从底部堆叠。Android:StaggeredGridLayoutManager初始化时滚动到顶部

我面临的问题是,在应用程序初始化时,图库底部的滚动点。当用户首次启动应用程序时,我希望滚动位于图库顶部。

我试过使用scrollToPosition(下面的代码片段),但随后滚动在画廊中间某处结束,可能是因为在调用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); 

有没有适当的方法将滚动指向顶部而不是底部?

回答

2

我解决过类似的问题,这里是方法:

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

和:

和:

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

的含义很简单:让RecyclerView总是滚动到顶部,直到你Ser触及它。希望这可以帮到你。

+0

它在我触摸屏幕时正常工作,但如果我不触摸屏幕,则无法显示。我想默认情况下滚动它,用户不需要触摸。这是最接近的答案,所以我会奖励你的奖金。顺便说一句,我的答案符合我的要求。 – uguboz

1

尝试通过调用 findFirstCompletelyVisibleItemPositions

findFirstVisibleItemPositions

与前面的方法(S)所获得的位置打电话给你回收视图scrollToPosition找到第一个可见的位置

+0

这并不能彻底解决问题。第一个可见项目并不总是最后一个项目。所以我可能会在不同的运行中滚动到不同的位置。 – Neo

0

使用scrollToPositionWithOffset()功能试用代替StaggeredGridLayoutManager。我发现它比scrollToPosition更可靠。还要确保在Handler().post()内执行此功能。这将导致Runnable被添加到消息队列中。它将在UI线程空闲时运行。

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

不幸的是它没有为我工作。 Thansk的答案 – uguboz

1

我用scrolltoposition内dataobserver,现在它工作正常..

当recyclerview负载,在上面的项目包括下面的代码可见:

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

      } 
     }); 

滚动至底部对于聊天视图中新添加的项目,请使用以下代码。

 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

看起来很有趣。 – Neo

0

此代码可以帮助你,我也使用这个代码链接

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

每个适配器视图(如ListView和GridView控件)已经为 支持绑定到被触发每当OnScrollListener事件一个 用户滚动浏览集合。使用这个系统,我们可以通过 定义 它支持大多数使用情况基本EndlessScrollListener创建我们自己的类,它扩展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 
    } 
    }