Stuck with updating adapter

huangapple go评论72阅读模式
英文:

Stuck with updating adapter

问题

我被困在一个相当简单的问题上 - 适配器更新。

我有一个包含Adapter1的Fragment,其中创建了N个项(垂直RecyclerView)。每个项都是一个具有NN个项的Adapter2(水平RecyclerView)。当滚动Adapter2时,我在Fragment的方法中加载更多的Adapter2项。

假设这是Adapter2中的代码:

// 为Adapter2加载更多项
if (position == getItemCount() - 1) {
    mFragment.loadMore(arg1, arg2, arg3);
}

这是来自Fragment的代码:

public void loadMoreModule(args) {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Handler handler = new Handler(Looper.getMainLooper());
    executor.execute(() -> {
        // 在此处进行后台工作
        downloadData(arg1, arg2, arg3);

        handler.post(() -> {
            // 在UI线程中进行工作
            Adapter1.notifyDataSetChanged();
            Adapter1.RecyclerViewForAdapter2Item.scrollTo(position);
        });
    });
}

就我理解,scrollTo() 在执行 notifyDataSetChanged()notifyItemRangeChanged(start, size) 之前执行,所以当加载新数据时,我遇到了一个问题 - 默认情况下,RecyclerViewForAdapter2Item 滚动到第一项。

Adapter1的示例代码:

Adapter1 {
    private Adapter2 adapter2;

    onBindViewHolder() {
        adapter2 = new Adapter2(args);
    }
}

加载的数据和position用于scrollTo() 都有正确的值。
由于与后端API一起工作时存在一些问题,我必须更新整个Adapter1并尝试滚动。我不能只更新Adapter2项。
是否应该重新设计与API的工作,以便我可以更新Adapter2,还是我现在可以以某种方式更新它?

英文:

I've stucked with pretty simple thing - adapter updating.

I have Fragment with Adapter1 inside which creating N items (vertical RecyclerView). Every item is Adapter2 which has NN items (horizontal RecyclerView). When scrolling Adapter2, I'm loading more items for Adapter2 in Fragment's method.

Let's say this is code in Adapter2:

// loading more items for Adapter2
if(position == getItemCount() - 1){
    mFragment.loadMore(arg1, arg2, arg3);
}

And this is code from Fragment:

public void loadMoreModule(args){
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Handler handler = new Handler(Looper.getMainLooper());
    executor.execute(() -> {
        // background work here
        downloadData(arg1, arg2, arg3);

        handler.post(() -> {
            // UI Thread work here
            Adapter1.notifyDataSetChanged();
            Adapter1.RecyclerViewForAdapter2Item.scrollTo(position);
        });
    });
}

scrollTo() like I understood executing before notifyDataSetChanged() or notifyItemRangeChanged(start, size) is done so when new data loaded I getting a problem - by default RecyclerViewForAdapter2Item scrolled to the first item.

Adapter1 sample code:

    Adapter1 {
        private Adapter2 adapter2;

        onBindViewHolder(){
            adapter2 = new Adapter2(args);
        }
   }

loaded data and position for scrollTo() have right values.
Due to some issues when working with backend API I must update the whole Adapter1 and try to scroll. I can't update Adapter2 item only.
Should be redone work with API so I could update Adapter2 or I can update it somehow now?

答案1

得分: 1

首先,是否有其他方法来更新整个适配器而不是调用NotifyDataSetChanged?NotifyDataSetChanged不是更新适配器的正确方法,您可以查找当前加载的数据与新加载的数据之间的差异,然后只更新发生更改的项目,这样您就不必自己滚动列表,滚动位置将保持不变。

当前,当您调用NotifyDataSetChanged更新整个适配器时,适配器会重新创建所有项目(包括嵌套的RecyclerView)。因此,如果内部项目被重新创建,滚动位置将丢失。

英文:

First of all, Is there any way around instead updated the wholde Adapter? NotifyDataSetChanged is not a correct way to update your adapter, you can find the differences between your currently loaded data and the new loaded data and then you can update only the items who change, this way you won't have to scroll the list by yourself, the scroll position will be maintained.

Currently when you updated the whole adapter calling notifyDataSetChanged the adapter is recreating all the items inside, (also your nested RecyclerView). So basicly if the items inside are being recrated, the scroll position will be lost.

huangapple
  • 本文由 发表于 2023年8月4日 03:32:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76831132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定