我正在使用StaggeredGridLayoutManager作为我的图片库。我已设置setReverseLayout(true)
,因此图片会从底部堆叠。
我面临的问题是,在应用初始化时,滚动点位于图库底部。当用户第一次启动应用程序时,我希望滚动位于库的顶部。
我已尝试使用scrollToPosition
(以下代码段),但滚动最终位于图库中间某处,可能是因为在调用{{1}时图像未正确加载}。
scrollToPosition
是否有正确的方法将滚动指向顶部而不是底部?
答案 0 :(得分: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);
}
}
}
});
和
mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mScrollByUser = true;
return false;
}
});
和
private void scrollRecyclerViewToTop() {
mRecyclerView.scrollToPosition(0);
mRecyclerView.scrollBy(0, Integer.MIN_VALUE);
}
意思很简单:让RecyclerView
始终滚动到顶部,直到用户触摸它。希望这可以帮到你。
答案 1 :(得分:1)
尝试通过调用找到第一个可见位置 findFirstCompletelyVisibleItemPositions
或findFirstVisibleItemPositions
调用您的回收者查看scrollToPosition与从前一个方法获得的位置
答案 2 :(得分:1)
请尝试使用scrollToPositionWithOffset()
的{{1}}功能。我发现它比StaggeredGridLayoutManager
更可靠。还要确保在scrollToPosition
中执行此功能。这将导致Handler().post()
添加到消息队列中。一旦UI线程空闲,它就会运行。
Runnable
答案 3 :(得分:1)
我在dataobserver中使用了scrolltoposition,现在它工作正常..
加载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);
}
}
});
答案 4 :(得分:0)
此代码可能会对您有所帮助,我也在代码中使用了这个链接
https://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView
每个AdapterView(例如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
}
}