具有动态ListView的Android ViewPager + Fragments

时间:2014-12-14 21:22:40

标签: android android-fragments android-listview android-viewpager fragmentstatepageradapter

在我的应用程序中,我有标签的活动(比方说10个标签)。每个标签页都包含FragmentListView(此ListView中显示的数据是从我的服务器动态加载的)。我使用ViewPager来显示这些页面。我不想将所有Fragments保留在内存中,所以我决定使用FragmentStatePagerAdapter(我的适配器类扩展了这些类)。

  1. 假设选择了第3个标签。然后,当我转到第一个标签时,应该从头开始创建此标签的Fragment(这很好,这是FragmentStatePagerAdapter的工作原理)但没有恢复以前的状态此片段(例如,ListView不应滚动到上次访问此Fragment时保存的位置 - 现在滚动)。 所以我的第一个问题是:我怎样才能实现这样的行为?换句话说,我希望我的适配器在从头开始创建时不要恢复Fragment状态。

  2. 再一次,让我们说第三个标签被选中。然后,当我去第二个标签时,此标签的Fragment应该仍然在内存中(这很好,这是FragmentStatePagerAdapter的工作方式),但在这种情况下我想决定是否{ {1}}数据应该更新(取决于某些条件)。如何通知此ListView它已被选中?

3 个答案:

答案 0 :(得分:0)

对于#1,请查看this博文。他们谈论修复FragmentStatePagerAdpater来处理索引的片段类发生变化的情况,这不是你想要的。但是,它详细显示了状态是如何保存/恢复的,您应该能够弄清楚如何从那里预防状态。

对于#2,在包含ViewPager的Fragment中实现OnPageChangeListener。然后使用this在更改时获取当前片段,以便您可以在其上调用一些公共方法,告诉它更新。

答案 1 :(得分:0)

  

我希望我的适配器在创建时不会恢复Fragmentstate   从头开始。

将以下代码添加到FragmentStatePagerAdapter

@Override
public int getItemPosition(Object object){
    return PagerAdapter.POSITION_NONE;
}
  

如何通知此片段已被选中?

当您在fragment的{​​{1}}中加载每个getItem时,也会使用getInstance(链接的示例很好)设计模式将位置传递给片段。在onPageSelected(int position)中调用LocalBroadcastManager并将位置作为额外内容。在每个片段中检查intent,如果extra中的位置与片段中存储的位置相同,则表示用户选择该片段,以便在fragmentStatePagerAdapter方法中更新列表。

答案 2 :(得分:-1)

对于#1,AFAIK,当转到第一个标签页时,与该标签相关联的片段会再次创建,就像它从未访问过一样,如果您使用了FragmentStatePagerAdapter。现在你说ListView是滚动的,你确定你正在使用 FragmentStatePagerAdapter ??

另一方面,如果您正在使用FragmentPagerAdapter,它会从FragmentManager中分离所有关闭的碎片但将它们保存在内存中,以便当您从第3个选项卡返回到第一个选项卡直接看到ListView保持最后状态。你提到的行为让我觉得你似乎正在使用FragmentPagerAdapter而不是FragmentStatePagerAdapter。

如果你确认那是FragmentStatePagerAdapter,我相信如果你不手动恢复状态(即在Fragment中使用onSaveInstanceState()方法),那么回来的Fragment肯定会在刚刚诞生时恢复。

对于#2,如果你想在Fragment完全可见时做某事,你可以覆盖setUserVisibleHint方法将你的代码放在那里。

public class YourFragement extend android.support.v4.app.Fragment {
    ...
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (conditions satisfied) {
            // do your job
        }
    }
    ...
}