gpt4 book ai didi

Android分页边界回调说明

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:21:12 26 4
gpt4 key购买 nike

我已经在我的应用程序中集成了分页组件,并且它运行良好(几乎)。我有数据库+网络模型。数据库最初有一些项目被 LivePagedListBuilder 使用.我观察到这个 LiveData<PagedList<InboxEntity>>并最终将列表提供给 PagedListAdapter#submitList(PagedList<T> pagedList) , 像这样的:

LiveData<PagedList<Entity>> entities;
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder()).setEnablePlaceholders(true)
.setPrefetchDistance(5)
.setEnablePlaceholders(false)
.setPageSize(10)
.setInitialLoadSizeHint(10)
.build();

entities = new LivePagedListBuilder<>(DAO.getItemList(), pagedListConfig)
entities.observe(this, new Observer<PagedList<Entity>>() {
@Override
public void onChanged(@Nullable PagedList<Entity> inboxEntities) {
inboxAdapter.submitList(inboxEntities);
isFirstLoad = false;
}
});

DAO#getItemList返回 DataSource.Factory<Integer, Entity> .

我正在监听边界回调并在到达分页列表末尾时触发网络调用。该调用再次填充数据库。

还有一件事。我注册了AdapterDataObserver在回收站 View 上,因为如果在开头插入了一个项目,我必须滚动到顶部位置:

RecyclerView.AdapterDataObserver adapterDataObserver = new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {

if (positionStart == 0) {
layoutManager.scrollToPositionWithOffset(positionStart, 0);
}
}
};

我在这个模型中遇到了一个问题:

进行网络调用后,数据库再次填充并且onChanged使用新的 PagedList<Entity> 调用函数.现在,此分页列表是否仅包含新项目。我已经证实了这一点。

但是onItemRangeInserted使用 positionStart 调用方法作为0同样,这表明项目是在开头插入的。但他们不是。它们被插入到最后,由 stetho db inspector 确认。

那为什么是onItemRangeInserted正在用 positionStart 调用作为0 ?这让我很难区分何时在适配器的开头插入新项以及何时在末尾插入项。

编辑:

itemCount 的值是 10,这是我的页面大小。

在DiffCallback中,我只是比较areItemsTheSame中两个实体的主键列功能。

最佳答案

我就是这样做的,虽然不理想,但确实有效。我正在使用将 reverse 设置为 true 的回收站 View ,因为它是一个聊天应用程序,因此您必须根据您的用例进行调整。

在您的 fragment 中创建一个计时器字段:

private Timer mTimer;

添加一个滚动状态监听器,设置一个“最新的行 ID”,您可以稍后进行比较。

 mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
//Get the latest id when we started scrolling
AppExecutors.getInstance().databaseIO().execute(() ->
mLatestMessageId = mHomeViewModel.getMessageViewModel().getLatestMessageId(mOurUsername, mChatname));
}
}});

调用插入时,使用 AdapterDataObserver 启动新计时器。

 private RecyclerView.AdapterDataObserver mAdapterDataObserver = new RecyclerView.AdapterDataObserver() {

@Override
public void onItemRangeInserted(int positionStart, int itemCount) {

if (mTimer != null) {
mTimer.cancel();
}


mTimer = new Timer();
mTimer.schedule(new CheckNewMessageTimer(), 100);

}
};

这是计时器类,如果插入了新项目,“最新行 ID”将在数据库中递增。如果我已经在底部,我只会滚动到底部,否则我只是更改我拥有的“滚动到底部”FAB 的颜色。

  class CheckNewMessageTimer extends TimerTask {
@Override
public void run() {
if (newItemsAdded()) {
int firstItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition();

boolean atBottom = firstItemPosition == 1;
SurespotLog.d(TAG, "CheckNewMessageTimer, firstItemPosition: %d, atBottom: %b", firstItemPosition, atBottom);

AppExecutors.getInstance().mainThread().execute(() -> {
if (atBottom) {
SurespotLog.d(TAG, "CheckNewMessageTimer, scrolling to bottom");
mListView.scrollToPosition(0);

}
else {
if (mFab != null) {
SurespotLog.d(TAG, "CheckNewMessageTimer, new message received but we're not scrolled to the bottom, turn the scroll button blue");
mFab.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.surespotBlue)));
}
}
});
}
}

private boolean newItemsAdded() {
int dbLatestMessageID = mHomeViewModel.getMessageViewModel().getLatestMessageId(mOurUsername, mChatname);

if (mLatestMessageId > 0 && dbLatestMessageID > mLatestMessageId) {
mLatestMessageId = dbLatestMessageID;
return true;
}

return false;
}
}

关于Android分页边界回调说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50231738/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com