问题 getParentFragment API 16


我们都知道 getParentFragment 的 Fragment 在API 17中引入。

那么如果我们想在API 16及更低版本中获取父片段呢(考虑到我使用native Fragment 有了支持 FragmentStatePagerAdapter 并且嵌套片段没有问题)

还有比我更好的方法吗?

在父母:

public class ParentFragment extends Fragment {

public static ParentFragment StaticThis;
...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

StaticThis = this;

...
}

在孩子:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
         parentFragment = (ParentFragment) getParentFragment();
else
         parentFragment = ParentFragment.StaticThis;

10804
2017-12-04 13:11


起源

直到API级别17或通过Android支持包,才支持嵌套片段。因此,在API级别17之前,没有“父级片段”的概念。您的“解决方案”是内存泄漏。 - CommonsWare
我正在使用ViewPager,需要从ViewPager的项目到容器进行对话。 @CommonsWare所以在API 17下面没有安全的方式与父片段(调用某些方法)进行对话? - Mohsen Afshin
由于API 17下面没有父片段,因此无法与API 17下的父片段进行通信。 - CommonsWare
@Snicolas:除了API Level 17+或使用片段backport之外,没有“父片段”的概念。如果您使用其中任何一种,请使用 getParentFragment()。 - CommonsWare
@CommonsWare,其他方式仍然可行。例如,我一直在寻找是否可以将每个片段的引用与其childMananger进行比较并递归循环遍历树,直到找到父片段(具有您的子片段具有子片段的管理器)。 - Snicolas


答案:


根据您的评论,如果您想从您的“项目”中回话 ViewPager (我猜这是一个 Fragment)到容器的 ViewPager 这是一个 FragmentActivity 你可以使用一个界面。

(1)声明接口中的接口 Fragment 本身或作为单独的文件 (2)“初始化”片段的onAttach方法中的接口。例如

 private SomeInterface blah;

 @Override
 public void onAttach(Activity activity){
    blah = (SomeInterface) activity;
 }

(3)在你的实现界面 FragmentActivity

然后你可以回电给 FragmentActivity 从你的 Fragment。从那里你可以调用你想要的任何方法 FragmentActivity 或者,如果您获得了加载到您的任何其他片段的引用 ViewPager,调用其中的任何公共方法 Fragment。这允许您在片段和容器之间进行通信而不会发生内存泄漏。


5
2017-12-04 13:46



父本身是Fragment not FragmentActivity,所以我不能使用onAttach,而是将它作为参数传递给子片段的构造函数 - Mohsen Afshin
好的 - 你仍然可以使用界面。这比静态参考更好。我的另一个想法是使用您从父级访问的内部抽象类。这样你可以通过这种方式回调主机片段。有点相同的概念。 - Rarw
接口是OO编程的重要组成部分。为什么会有这么多问题? - danny117
Idk问那个问这个问题的人 - Rarw


为了获得较旧(和较新)版本的父片段,我找到了解决方法:

1)在您的活动中设置ParentFragment的标签(通过.add()或.replace())。请查看以下链接以获取更多信息,或者在ParentFragment中查看类似示例的步骤2: http://developer.android.com/reference/android/app/FragmentTransaction.html#add(android.app.Fragment,java.lang.String)

2)在ParentFragment中,收集标签(使用'this'),并将其添加到ChildFragment的newInstance()中:

  FragmentManager fragmentManager = getFragmentManager();
  FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

  // Get the fragment, if you want to re-use it
  ChildFragment fragment = (ChildFragment) fragmentManager.findFragmentByTag();

  // Create a new fragment if it doesn't already exist.
  if (fragment == null)
  {
     // Collect the tag of your ParentFragment and add it to the newInstance() of the ChildFragment
     String parentTag = this.getTag();
     fragment = ChildFragment.newInstance(parentTag);
  }
  // Put the fragment in the .replace() or .add() of the transaction.
  // You might use a childTag as well, but it's not necessary for solving your problem
  fragmentTransaction.replace(R.id.my_fragment_view, fragment, childTag);
  fragmentTransaction.commit();

3)确保将标记保存在ChildFragment的参数中。从onAttach()中的参数中收集标记,并通过onAttach()中的'activity'参数收集ParentFragment:

private static final String PARENT_TAG = "parent_tag";
ParentFragment parentFragment;

public static ChildFragment newInstance(String parentTag)
{
   ChildFragment fragment = new ChildFragment();
   Bundle args = new Bundle();
   args.putString(PARENT_TAG, parentTag);
   fragment.setArguments(args);
   return fragment;
}

@Override
public void onAttach(Activity activity)
{
   super.onAttach(activity);

   // Collect the tag from the arguments
   String tag = getArguments().getString(PARENT_TAG);

   // Use the tag to get the parentFragment from the activity, which is (conveniently) available in onAttach()
   parentFragment = (ParentFragment) activity.getFragmentManager().findFragmentByTag(tag);
}

4)现在你的ChildFragment已经在你的ChildFragment中了,你可以在需要的时候使用它,所以你在这里使用它:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
     parentFragment = (ParentFragment) getParentFragment();
}
else
{
     parentFragment = ParentFragment.StaticThis;
}

你现在可以:

parentFragment.justDoSomethingCoolWithIt(); // and prevent memory leaks through StaticThis ;-)

4
2018-04-23 16:36





简单使用支持图书馆的碎片活动。 http://developer.android.com/reference/android/support/v4/app/Fragment.html#getParentFragment%28%29


4
2018-06-24 08:05



哦,太棒了,这真的很有帮助。 api名称相同,getParentFragment()因此存在混淆,认为...... API <16不存在此功能。但是,您可以添加更多描述,以便让人们了解它。谢谢 - Nicks