【问题标题】:FragmentPagerAdapter with ViewPager and two Fragments. Go to the first from the second and update first's textFragmentPagerAdapter 带有 ViewPager 和两个 Fragment。从第二个转到第一个并更新第一个的文本
【发布时间】:2012-04-18 19:32:01
【问题描述】:

我不熟悉FragmentPagerAdapter,所以这将是我们(你)认真阅读描述的问题之一。

结构:我有一个FragmentPagerAdapter(代码如下),它一次可以容纳两个片段。第一个显示书摘,第二个显示书名列表。

目标:我想实现标题中描述的:用户可以导航到分页器中的第二个片段,点击一个标题,然后我想将用户移回第一个片段并告诉第一个片段更新文本。第一个片段有一个triggerRefresh 方法。

代码:我相信我的问题是因为FragmentPagerAdapter 重用/创建片段的方式(我不明白)。这是我的课:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
        case 0:
            return new ExcerptsFragment();
        case 1:
            return new BookListFragment();
        default:
            throw new IllegalArgumentException("not this many fragments: " + position);
        }
    }
}

这就是我创建相关成员的方式:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
MyFragmentPagerAdapter mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);

这是我在 Activity 的其他地方尝试过的,当我收到来自书名 Fragment 的回调时,选择了标题:

mViewPager.setCurrentItem(0); // back to excerpts screen page. It's OK.
// Here's the problem! How to identify the fragment 0 
// to ExcerptsFragment and call its triggerRefresh()?!?

系列问题:

调用适配器的getView() 将不起作用,因为它将返回ExcerptsFragment 的新实例,它不是当前附加的实例(如预期的那样,引发异常)。

我在这里看到很多人 (example) 只是将片段存储在 getView() 中。那正确吗?因为通过查看官方示例,对我来说似乎是一种反模式(通过持有项目来击败自动参考)。这也是herehere 的意见(在我看来是正确的)。

有什么建议吗?如果我一点都不了解这一切,我不会感到惊讶......

【问题讨论】:

    标签: android android-fragments android-viewpager updating fragmentpageradapter


    【解决方案1】:

    免责声明:虽然这对我来说之前效果很好,你应该知道依赖内部私人行为的经典陷阱。虽然我编写的测试最终会在内部实现发生变化时警告我,但我已经转向greener pastures。你也应该这样做。因此,在我看来,这个问题及其答案的价值只是历史性的。


    抱歉这个问题,我想是时候了。

    为了解决这个问题,我按原样实现了this solution。似乎工作得很好。所以,我相信这只是通过弄清楚它的 Id 是如何命名的来找到(当前附加的)片段实例的问题。上面的链接解释了它是如何制作的。

    我选择回答我自己的问题而不是删除它,因为我相信像我这样的寻呼机新手将从“真实案例场景”中受益。我看到的大多数答案都在谈论理论,顺便说一句,这是正确的方法......但没有一个真实的例子可以研究有时像我这样的人会迷路。

    无论如何,这是我需要的最后一段代码(上面的注释部分):

    int n = 0;
    mViewPager.setCurrentItem(n); // in the question I had stopped here.
    
    ExcerptsFragment f = (ExcerptsFragment) ContainerActivity.this
            .getSupportFragmentManager().findFragmentByTag(getFragmentTag(n));
    f.triggerRefresh();
    
    // ... below the helper method: used the solution from the link.
    
    private String getFragmentTag(int pos){
        return "android:switcher:"+R.id.pager+":"+pos;
    }
    

    所以,我感觉这是一个强大的解决方案,因为我没有持有任何对片段的引用(因此存在引用过时的风险)。我将自己的代码保持在最低限度,从而最大限度地减少我做蠢事的机会。

    当然,如果您有什么要补充、向我们展示、告诉我们这样做的问题或可以改进的地方,我会很高兴收到您的来信。 p>

    【讨论】:

    • 您不应依赖与分配标签的内部机制的兼容性。请参阅我对类似问题的回答如何正确执行此操作:stackoverflow.com/questions/14035090/…
    • @morgwai 谢谢你的警告。我加入了免责声明以警告潜在读者。
    • 不客气 :) 我认为最好直接提供指向我的答案的链接(不仅是那个问题),因为我的答案非常新,因此得分仍然很低,所以读者可能只是坚持 2 个得分最高的答案之一,这两个答案都有问题。 (我在我的回答中添加了一些解释,为什么覆盖 instantiateItem 的解决方案本身可能还不够)
    • 对不起,我必须通过。我从不直接或间接链接或以其他方式认可我(仍然)没有使用、测试或确认的解决方案(如前所述,我已经从答案中的“解决方案”(引用)继续前进了很长一段时间现在)。作为个人评论,我建议您不要担心赞成票和知名度。如果这些年来我在 SO 上注意到的一件事是用户找到最佳答案并为他们投票,如果他们有问题并且解决方案更好,则解决他们的问题。不要担心这个。如果其他答案有问题,让用户自己判断。 ;-)
    • 我并不真正关心我的 UIP(无用的互联网积分),而是关心人们被高分错误答案误导,但无论如何 ;)
    【解决方案2】:

    我自己搜索了一段时间来解决这个问题。您的方法原则上有效,但如果 Android 基类实现中的片段标记创建代码发生更改,它将破坏您的代码。这是一个非常讨厌的依赖!

    更优雅的方法是解决问题并在片段中保留一个基本活动实例。在您的活动中为标签实现一个设置器,并在创建时在片段内调用它 - 那里的标签只需使用 getTag() 即可。

    可以在here找到一个示例实现。

    【讨论】:

    • 迄今为止这个非常随机问题的最佳解决方案。但是有两件事:您可以使用 getActivity() 获得对“父活动”的引用。而且您需要记住,您需要通过配置更改保留标签名称,因为即使可能重新创建适配器,片段也可能不会(因此不会再次设置标签)
    【解决方案3】:

    我通过在创建片段时使用 Wea​​kReferences 解决了这个问题。见:https://stackoverflow.com/a/23843743/734151

    如果您发现此方法有任何问题,请发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      相关资源
      最近更新 更多