首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查看器只更新当前可见的片段

查看器只更新当前可见的片段
EN

Stack Overflow用户
提问于 2020-03-18 21:49:50
回答 1查看 4.2K关注 0票数 0

我在viewpager fragments中更新了fragments,并调用pagerAdapter.notifyDataSetChanged();更新它们。它更新了所有的循环视图,应用程序花费了很长时间。现在,为了克服这个问题,我只想更新当前可见的片段,在ViewPage上更改,用notifyDataSetChanged();更新其他片段,有办法知道要更新哪个片段吗?

ViewPagerAdapter

代码语言:javascript
复制
 private class MyPageAdapter extends FragmentStatePagerAdapter {
            private List<Fragment> fragments;
            private int[] mResources;

        public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }

        @Override
        public Fragment getItem(int position) {

            return this.fragments.get(position);

        }

        @Override
        public int getCount() {
            return this.fragments.size();
        }

        @Override
        public int getItemPosition(Object object) {
            MyFragment f = (MyFragment) object;
            if (f != null) {
                f.update();
            }
            return super.getItemPosition(object);
        }
    }

这是片段

代码语言:javascript
复制
public static class MyFragment extends Fragment implements CustomAdapterOdds.OnGameClickListener, Updateable {
        public static final String COLUMN_IN_DISPLAY = "column_in_display";


        RecyclerView recyclerView, recyclerView2;
        HashMap<String, List<OddsFeed>> oddsList1;
        HashMap<String, List<OddsFeed>> oddsList2;
        int oddsColDisp;
        CustomAdapterOdds adapterOdds1, adapterOdds2;

        boolean isvisible = false;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            oddsList1 = new HashMap<>();
            oddsList2 = new HashMap<>();
            Bundle b = this.getArguments();
            oddsColDisp = b.getInt(COLUMN_IN_DISPLAY);
            List<GameFeed> leftGames = getArguments().getParcelableArrayList("list");
            if (b.getSerializable("hashmap1") != null && b.getSerializable("hashmap2") != null) {
                oddsList1 = (HashMap<String, List<OddsFeed>>) b.getSerializable("hashmap1");
                oddsList2 = (HashMap<String, List<OddsFeed>>) b.getSerializable("hashmap2");
            }

            View v = inflater.inflate(R.layout.view_table_viewpager_fragment_layout, container, false);

            ArrayList<GameFeed> gameFeedsCol0 = getArguments().getParcelableArrayList("list");

            //recycleview1
            recyclerView = v.findViewById(R.id.table_view_recycle_view_odds1);
            adapterOdds1 = new CustomAdapterOdds(getContext(), leftGames, this, oddsList1, bestSitesList, oddsColDisp);
            configRecyclerViewOdds(getContext(), recyclerView, adapterOdds1);

            //recycleview2

            recyclerView2 = v.findViewById(R.id.table_view_recycle_view_odds2);
            adapterOdds2 = new CustomAdapterOdds(getContext(), leftGames, this, oddsList2, bestSitesList, oddsColDisp + 1, true);
            configRecyclerViewOdds(getContext(), recyclerView2, adapterOdds2);

            return v;
        }


        @Override
        public void setMenuVisibility(final boolean visible) {
            super.setMenuVisibility(visible);
            if (visible) {
                isvisible = true;
            }
        }

        @Override
        public void onResume() {
            super.onResume();
            Toast.makeText(getContext(), "onresume", Toast.LENGTH_SHORT).show();
            adapterOdds1.updateListOdds(leftGames, oddsList1, oddsColDisp);
            adapterOdds2.updateListOdds(leftGames, oddsList2, oddsColDisp + 1);

        }

        @Override
        public void OnGameClickListener(View view, int position) {

        }

        @Override
        public void update() {

            Toast.makeText(getContext(), "update", Toast.LENGTH_SHORT).show();
            if (isVisible()) {
                adapterOdds1.updateListOdds(leftGames, oddsList1, oddsColDisp);
                adapterOdds2.updateListOdds(leftGames, oddsList2, oddsColDisp + 1);
             updateViewpager++;
                int size = bestSitesList.size() / 2;

                adapterOdds1.updateListOdds(leftGames, oddsList1, oddsColDisp);
                adapterOdds2.updateListOdds(leftGames, oddsList2, oddsColDisp + 1);

                if (updateViewpager == size - 1) {
                    progressBar.setVisibility(View.INVISIBLE);
                    updateViewpager = 0;
                }
           }
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2020-03-19 01:05:17

很抱歉,这是一个杂乱无章的答案,但是没有给出足够的代码示例来给出一个有效的答案,所以更多的是试图解释一个概念。确实需要数据更新的时间和方式的细节,但是.

在使用androidx时,您可能需要考虑迁移到viewpager2,或者使用viewpager可以更改片段生命周期状态的管理方式。

如果在构建适配器BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT https://developer.android.com/reference/androidx/fragment/app/FragmentStatePagerAdapter#BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT时更改为使用https://developer.android.com/reference/androidx/fragment/app/FragmentStatePagerAdapter#FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager,%20int)

然后,所有片段只有在创建或重新创建时才会显示为“启动”,只有当前屏幕上的片段“恢复”,然后当移出屏幕时“暂停”。

确切的机制取决于碎片回收视图是如何获得数据的,以及是什么触发了更新,但是一般的想法是,碎片onCreateView创建布局的轻量级"shell“,我基本上有静态按钮/文本,并使用一个空的数据集创建回收视图。

然后,在片段的onResume方法(只对当前屏幕上的片段进行调用)中,它调用您的update方法,用实际的数据集替换两个回收视图的空数据集,并对回收视图执行notifyDataSetChanged()

因此,当最初创建viewpager时,会创建X个片段,然后在那里布局静态内容,再加上1个片段(当前屏幕上的片段),得到填充了实际数据的回收视图。

然后,您还可能希望在片段的onResume中添加一些优化检查,以检查回收视图视图数据实际上已经更改(简单大小检查或使用回收视图的DiffUtils),否则,当您在查看器中的片段之间移动时,每个片段将被暂停/恢复。

这实际上只会延迟片段中的两个回收视图的成本,直到真正需要时(当它即将被显示出来时),这是一种“延迟加载”的形式。

通过将“动态”数据移动到这个“延迟加载”中,可以消除对片段进行notifyDataSetChanged的需要,但是代码片段并没有充分显示回收视图内容变化的方式和原因。

使用此方法绘制数据时会发生更改,您可能不喜欢它的外观。

这实际上是一个高级别的片段更新逻辑的反转,而不是说“数据改变了在所有片段中重新绘制数据”,而是“显示了这个片段,如果数据自我上次绘制以来已经更改了它”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60747988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档