FragmentPagerAdapter动态更新标题

19

我有一个带有FragmentPagerAdapter的ViewPager,其中包含3个片段。现在,我在片段的标题中有一些项目

enter image description here

因此,用户可以添加或删除这些项目,并且标题应相应更新。但是,这个标题似乎是静态的。

如何调用此方法以更新FragmentPagerAdapter的标题?

@Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0: return items + " (" + notFoundItems + ")";
            case 1: return found;
            case 2: return review;
        }
        return "";
    }

我在Stack Overflow上找到了一些类似的问题,但是我需要更新标题,而不仅仅是片段本身。

7个回答

9

最终,我通过简单地重新设置分页器来解决了问题。

private OrdersTabsAdapter tabsAdapter;
@InjectView(R.id.tabs_orders) SlidingTabLayout ordersTabs;
@InjectView(R.id.pager) ViewPager pager;

public void update() {
  tabsAdapter.updateFragments(productId, status);
  ordersTabs.setViewPager(pager); //this helped with the titles
}

与其调用 'setViewPager()',最好调用 'setTabsFromPagerAdapter(PagerAdapter adapter)'。这具有完全相同的效果('setViewPager()' 在内部调用此方法),并且您可以跳过一些额外的工作,因为 'setViewPager()' 还设置了一些侦听器。基本上它只是删除并重新添加所有选项卡。虽然存在一些私有的 'update' 方法,但即使使用反射调用它们,它们似乎也不会对标题产生任何影响。 - Stefan de Bruijn
mTabs.setViewPager(pager); 只需要这样就可以了! - Robert
嗨,我成功地让适配器中的update()方法被调用了,但是你能告诉我如何在getPageTitle中更改标题吗?即使getCount返回一些值,我的方法似乎也没有被调用。 - emen

9
作为其下评论所建议的,我认为被接受的答案有些过度。基于Frank的答案,我已经采取了以下措施:
public void myUpdatePageTitle(int pagePosition, int numItems) {
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    TabLayout.Tab tab = tabLayout.getTabAt(pagePosition);
    if (tab != null) {
        tab.setText(myCalcTabTitle(pagePosition, numItems));
    }
}

private String myCalcTabTitle(int pagePosition, int numItems) {
    //TODO - For this page, return whatever title string you like, including the numItems value. (The best way to do this is using a string resource that accepts a decimal parameter.)
}

1
我已经审查了许多答案,对我来说这可能是性能方面最好的答案。当然,调用notifyDataSetChanged()会起作用,但如果在每个片段中都进行重型操作或连接到互联网,那就真的很糟糕了。 - Roberto

5
好的,那么您可以在FragmentPagerAdapter中编写一个方法来更新notFoundItemsfoundItemsitemsForReview的数量。 在更新完后,调用notifyDataSetChanged()方法即可。
 @Override
 public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0: return items + " (" + notFoundItems + ")";
            case 1: return found + " (" + foundItems + ")";
            case 2: return review + " (" + itemsForReview + ")";
        }
        return "";
 }

同时,将以下内容添加到您的FragmentPagerAdapter类实现中。因此,每当您有新的数据计数并想要更新标题时,请调用此方法。

 public void updateTitleData(int notFoundItems, int foundItems, int itemsForReview) {
      this.notFoundItems = notFoundItems;
      this.foundItems = foundItems;
      this.itemsForReview = itemsForReview;
      notifyDataSetChanged();
 }

1
抱歉,但它没有起作用。我之前尝试过使用notifyDataSetChanged();,但它无法更新标题。 - Roman
@Roman 你看过 viewpagerindicator 吗?那个库有 TitlePageIndicator。你在用这个吗? - ngoa
notifyDataSetChanged() 在自定义的 FragmentPagerAdapter 中起作用。 - d4c0d312

5

你有3个片段,因此你将使用3个选项卡(第一个选项卡具有索引0,第二个选项卡为1,第三个选项卡为2)。通过索引获取你的选项卡,并设置其文本标题。希望这可以帮助你,兄弟。

示例:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.getTabAt(index).setText("");

2
我认为重置ViewPager和调用notifyDataSetChange并不是一个好的方法。因为这将导致ViewPager中的视图重新创建,这是不必要的。我发现另一种解决问题的方法。
    List<OrderListResult.TradeStatusVOsEntity> tradeStatusVOs = updateTitleEvent.getTradeStatusVOs();
    for (int i = 0; i < tradeStatusVOs.size(); i++) {
        OrderListResult.TradeStatusVOsEntity tradeStatusVOsEntity = tradeStatusVOs.get(i);
        int num = tradeStatusVOsEntity.getNum();
        String text = mAdapter.getPageTitle(i).toString();
        if (num > 0) {
            text = text + "(" + num + ")";
        }
        mButterTabs.getTabAt(i).setText(text);
    }

    mButterTabs.setTabTextColors(getResources().getColor(android.R.color.darker_gray),
            getResources().getColor(R.color.yellow));
首先,你需要使用TabLayoutgetTabAt方法来更改选项卡的模型。然后调用setTabTextColors来更新视图。因为从TabLayout的源代码中,setTabTextColors将逐一更新所有选项卡。

2

每次重新设置您的页面都没有意义。
您已经覆盖了getPageTitle(),只是需要跟踪页面何时更改以及何时更新标题。
所以您可以轻松地这样做:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        // your tite is: mAdapter.getPageTitle(position));
        // TODO: update title
    }
});

此外,您需要在onCreate()中设置初始标题。


0

TabLayout.OnTabSelectedListener 在重新设置 ViewPager 时会被触发,因此我建议自己更新标题。

viewPager.adapter?.apply {
    for (p in 0..count) {
        tabLayout.getTabAt(p)?.text = getPageTitle(p) ?: break
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,