FragmentPagerAdapter与ViewPager和两个片段。 从第二个开始,更新第一个文本

我对FragmentPagerAdapter不熟悉,所以这将成为我们(你)严格阅读这些描述的问题之一。

结构:我有一个FragmentPagerAdapter (下面的代码),它将一次容纳两个片段。 第一个显示书籍摘录,第二个书目名单。

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

代码:我相信我的问题发生是因为FragmentPagerAdapter重用/创build碎片(我不明白)的方式。 这是我的class级:

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

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

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

这是我在我的活动中尝试过的其他地方,当我收到书名为Fragment的select标题的callback:

 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的新实例,该实例不是当前附加的实例(如预期的那样引发exception)。

我在这里见过很多人( 例如 )在getView()存储片段。 是对的吗? 因为通过查看官方的例子,似乎对我来说是一个反模式(通过持有这些项目来击败自动引用)。 这也是在这里和这里的意见(和我看来是对的)。

有什么build议么? 如果我不了解所有这一点,我不会感到惊讶。

免责声明: 尽pipe以前这对我来说工作得非常好,但您应该意识到取决于内部私人行为的经典缺陷 当我写testing,最终会警告我,如果内部实施改变,我已经转移到绿色的牧场 。 而且你也应该。 因此,在我看来,这个问题的价值及其答案只是历史的。


对不起这个问题,我想是时候了。

为了解决这个问题,我实现了这个解决scheme 。 似乎工作得很好。 所以,我相信这只是find(当前附加)片段实例的问题,通过计算出它的Id是如何命名的。 上面的链接解释了它是如何制作的。

我select回答我自己的问题,而不是删除它,因为我相信这些传呼机上像我这样的新手会受益于“真实的情况下”。 我所见过的大多数答案都是关于理论的,这是正确的方式,但是没有一个真正的例子可以让有时候像我这样的人迷失方向。

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

 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; } 

所以,我有一种感觉,这是一个强大的解决scheme,因为我没有持有任何引用片段(从而冒险引用过时)。 我至less保留自己的代码,因此尽量减less我做一些愚蠢的事情。

当然,如果你还有什么要补充的,告诉我们,告诉我们做错了什么或者可以改进什么,我很乐意听到你的消息。

我自己找了一个解决这个问题的方法。 原则上你的方法是可行的,但如果在Android基类实现中创build片段标签的代码发生变化,它将会破坏你的代码。 这是一个相当讨厌的依赖!

一个更优雅的方法是将问题转移到你的片段中,并保留基本活动的一个实例。 在您的活动中为标记实现一个setter,并在创build时调用该标记内部的标记 – getTag()可以简单地使用该标记。

一个示例实现可以在这里find。

我通过在创build时使用WeakReferences来解决这个问题。 请参阅: https : //stackoverflow.com/a/23843743/734151

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