我在viewpager fragments中更新了fragments,并调用pagerAdapter.notifyDataSetChanged();更新它们。它更新了所有的循环视图,应用程序花费了很长时间。现在,为了克服这个问题,我只想更新当前可见的片段,在ViewPage上更改,用notifyDataSetChanged();更新其他片段,有办法知道要更新哪个片段吗?
ViewPagerAdapter
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);
}
}这是片段
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;
}
}
}
}发布于 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的需要,但是代码片段并没有充分显示回收视图内容变化的方式和原因。
使用此方法绘制数据时会发生更改,您可能不喜欢它的外观。
这实际上是一个高级别的片段更新逻辑的反转,而不是说“数据改变了在所有片段中重新绘制数据”,而是“显示了这个片段,如果数据自我上次绘制以来已经更改了它”。
https://stackoverflow.com/questions/60747988
复制相似问题