【问题标题】:FragmentStatePagerAdapter / Update Action Bar TitleFragmentStatePagerAdapter / 更新操作栏标题
【发布时间】:2013-05-11 00:05:55
【问题描述】:

我有一个带有 ViewPager+FragmentStatePagerAdapter 的主机活动,它让我可以浏览一组片段(同一 ItemFragment 类的不同实例),并且从网络获取用于填充每个片段的数据。

现在,当我滑动时,我想使用来自当前片段的属性更新操作栏标题,因此我使用 OnPageChangeListener/onPageSelected 来完成这项工作:

...
@Override
public void onPageSelected(int position) {
    MyFragment currentFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.view_pager);
    getSupportActionBar().setTitle(currentFragment.propertyIWantToUseAsTitle);
}
...

我有几个疑问:

  • 我正在检索真正的当前片段吗? FragmentStatePageAdapter 没有为每个片段设置标签,所以我不知道有什么其他方法可以获取当前片段,而不是使用 ViewGroup 容器
  • 当调用 onPageSelected 时,添加的片段可能仍在获取我需要设置操作栏标题的数据,从而导致 npe。

在上述场景中保持更新操作栏标题的逻辑的最佳位置是什么?

ps。我尝试了一种混合方法,将代码添加到 MyFragment 以在我需要的数据可用时更新 ab。问题是很少有片段被提前加载,并且随着片段完成加载而动作栏标题发生变化。结果是 ab 标题是来自前几页片段的随机标题。

提前感谢您的帮助!

【问题讨论】:

  • “我正在检索真正的当前片段吗?” -- 也许现在,但您依赖于ViewPager 实现细节,这是有风险的。 “FragmentStatePageAdapter 没有为每个片段设置标签”——您是否仅限于使用 FragmentStatePagerAdapter? “在上述场景中,保持更新操作栏标题的逻辑的最佳位置是什么?” - 是的,我真的需要为此制定一个解决方案。它现在正式在我的待办事项清单上。
  • 感谢@CommonsWare,我刚刚成功,但我担心内存使用情况。看看这里gist.github.com/gwvatieri/5544164

标签: android android-fragments android-actionbar android-viewpager


【解决方案1】:

我在Fragment 本身中设置了ActionBar 标题。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Bundle extras = getActivity().getIntent().getExtras();
    type = (String) extras.getString("type");
}// end method

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {
        Activity activity =  getActivity();
        ActionBar actionBar = activity.getActionBar();

        if (type.equals("one")) {
            actionBar.setTitle(R.string.one);
        }
        if (type.equals("two")) {
            actionBar.setTitle(R.string.two);
        }
        if (type.equals("three")) {
            actionBar.setTitle(R.string.three);
        }
    } 
}//end method   

【讨论】:

    【解决方案2】:

    AFAICT,当新页面设置为“当前”时,应使用 setPrimaryItem() 调用您的 PagerAdapter。您可以覆盖该方法,链接到超类,然后将ObjectsetPrimaryItem() 的第一个参数)转换为适当的Fragment 类并对其进行处理。那个“东西”可能会将其存储在您的 PagerAdapter(例如 currentPage)的数据成员中,并添加一个 getter 以便以后能够检索它。

    【讨论】:

    • 做了一个快速测试,由于某些原因,onPageSelected 回调有时会早于 setPrimaryItem 触发,导致操作栏具有上一个或下一个项目的标题。另外,调用 setPrimaryItem 会导致延迟(顺便说一句,它被多次触发)......
    • @gwa:“由于某些原因,onPageSelected 回调有时会在 setPrimaryItem 之前触发,导致操作栏具有上一个或下一个项目的标题”——所以?从setPrimaryItem() 更新操作栏。恐怕我没有关注您的其余评论。
    • 好吧,这是有道理的,只是删除了保留对片段的引用的地图。感谢您的帮助。下周你会去 IO 吗?
    • @gwa:不。部分原因是我在 57 毫秒内没有空票... :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2013-12-04
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多