android RecyclerView在Viewpager2选项卡变更时未显示更新列表

lsmd5eda  于 2023-02-11  发布在  Android
关注(0)|答案(1)|浏览(233)

在我的安卓应用中,我使用TabLayout和ViewPager2来显示RecyclerView中不同类别的列表。当我进行添加和删除操作,然后调用notifyDataSetChanged时,列表会发生变化,而我仍然在当前选项卡上。然而,当我选择另一个选项卡并返回时,列表显示的是创建片段时初始化的原始项目。
FragmentStateAdapter适配器类的createFragment函数中,我使用起始数据项arraylist初始化了一个片段,如下所示。

public class DataListAdapter extends FragmentStateAdapter {
    private DataListFragment[] fragments;

    //
    // other code
    //

    @Override
    public Fragment createFragment(int position) {
        ArrayList<DataItem> dataItems;

        //The actual code returns a different data item based on conditions
        dataItems = dbAdapter.getDataItems();

        DataListFragment frag = new DataListFragment(dataItems);

        fragments[position] = frag;

        return frag;
    }
}

在DataListFragment中,我有...

DataListFragment(ArrayList<DataItem> dataItems) {
    this.dataItems.addAll(dataItems);
}

为了确保在选择选项卡时拥有最新的ArrayList,我在活动中编写了以下代码...

dlBinding.tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        dlAdapter.refreshFragmentDataItems(tab.getPosition());
    }
});

适配器的相关代码:

public void refreshFragmentDataItems(int position) {
    ArrayList<DataItem> dataItems;

    dataItems = dbAdapter.getRecentDataItems(null);

    fragments[position].setDataItems(dataItems);
}

最后是Fragment类中的setDataItems()代码:

public void setDataItems(ArrayList<DataItem> dataItems) {
    this.dataItems.clear();
    this.dataItems.addAll(dataItems);
    recyclerAdapter.notifyDataSetChanged();
}

在调试代码时,即使不执行refreshFragmentDataItems()函数,我也注意到,在考虑了ArrayList中的任何添加和删除项之后,fragments[position].dataItems变量具有最新的项列表。
尽管如此,它仍然显示原始列表。我试图移动notifyDataSetChanged()调用,但无济于事。在某些情况下,它将进入一个永久循环。
将感谢任何投入,在弄清楚为什么我的回收视图中的列表没有更新时,我选择另一个标签。

    • 编辑:**进一步诊断后,我发现问题是由搜索功能引起的。

我有一个QueryTextListener,在OnQueryTextChange中注解掉代码可以解决这个问题。

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                InputMethodManager inm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                inm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
                dlAdapter.getFragment(dlBinding.tabs.getSelectedTabPosition()).filterAdapter(query);
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                //comment below line to fix issue

获取片段(获取选定标签位置());过滤器适配器(新文本);返回真;}});
这是过滤RecyclerView适配器的函数。

public void filterAdapter(String query) {
    recyclerAdapter.getFilter().filter(query);
}

当我调试上述两个函数中的所有步骤时,监 windows 格中的项计数反映了实际计数,但当调试步骤完成时,它仍然显示一个较早删除的项。

jfewjypa

jfewjypa1#

为了便于将来使用,如果您要在同一Activity中的片段之间切换,可以执行以下操作:
在您的onStop()/onDestroyView()/onPause()中,无论哪个回调更合适,请执行以下操作:

static Parcelable recyclerViewState;

@Override
public void onPause() // or onStop or onDestroyView
{
    recylerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
}

在你的onStart()/onCreateView()/onResume()中,无论哪个回调更合适,都可以这样做:

@Override
public void onResume() // or onStart or onCreateView
{
    recyclerView.getLayoutManager().onRestoreInstanceState(recylerViewState);
}

这样,您就可以成功地将recyclerView的状态保持为可打包状态,并在需要时恢复它。
别忘了补充:

@Override
public void onDestroy()
{
    recylerViewState = null;
}

相关问题