【问题标题】:FragmentPagerAdapter update title dynamicallyFragmentPagerAdapter 动态更新标题
【发布时间】:2015-04-30 15:45:55
【问题描述】:

我有一个带有 FragmentPagerAdapter 的 ViewPager,它有 3 个 Fragment。现在,我有一些项目作为片段标题的一部分

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

如何回忆起这种更新 FragmentPagerAdapter 标题的方法?

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

我在 SO 上发现了几个类似的问题,但我需要更新 title,而不仅仅是片段本身。

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    最后,我通过简单地重新设置寻呼机解决了它。

    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()' 还设置了一些侦听器。基本上它所做的一切都是删除并重新添加所有选项卡。有一些私有的“更新”方法,但即使使用反射调用,它们似乎对标题没有任何影响。
    • mTabs.setViewPager(pager); 会做到的!
    • 您好,我设法在适配器中调用了update() 方法,但您能告诉我如何更改getPageTitle 中的标题吗?即使getCount 返回一些值,我的似乎也没有被调用。
    【解决方案2】:

    正如它下面的一个 cmets 所暗示的那样,接受的答案对我来说似乎有点矫枉过正。

    基于Frank's answer,这是我所做的:

    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.)
    }
    

    【讨论】:

    • 我一直在审查许多答案,对我来说这可能是性能方面最好的。当然调用 notifyDataSetChanged() 会起作用,但如果在每个片段中你都在做繁重的操作或连接到 Internet,那真的很糟糕。
    【解决方案3】:

    好的。所以你可以在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();
     }
    

    【讨论】:

    • 很抱歉,它不起作用。我试过 notifyDataSetChanged();之前,它不会更新标题。
    • @Roman 你看过viewpagerindicator。那个图书馆有TitlePageIndicator。你在用这个吗?
    • notifyDataSetChanged() 在自定义 FragmentPagerAdapter 中工作
    【解决方案4】:

    您有 3 个片段,因此您将使用 3 个标签(第一个标签有索引 0,第二个 1,第三个 2)。 使用索引获取您的标签并将她的文本设置为标题。 希望对你有帮助

    例子:

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

    【讨论】:

      【解决方案5】:

      我不认为重置 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会一一更新所有的tab。

      【讨论】:

        【解决方案6】:

        每次都重新设置寻呼机是没有意义的。
        您已经覆盖了 getPageTitle(),只是缺少跟踪页面何时更改以及何时更新标题的时间。
        所以你可以很容易地做到这一点:

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

        您还必须在 onCreate() 中设置初始标题

        【讨论】:

          【解决方案7】:

          TabLayout.OnTabSelectedListener会在用ViewPager重新设置时触发,所以我建议自己更新标题。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-22
            • 2020-09-29
            • 1970-01-01
            • 1970-01-01
            • 2023-03-07
            • 2018-10-22
            相关资源
            最近更新 更多