【问题标题】:getParentFragment API 16getParentFragment API 16
【发布时间】:2014-06-24 16:05:59
【问题描述】:

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

如果我们想在 API 16 及以下获取父片段怎么办(考虑到我使用原生 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;

【问题讨论】:

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

标签: android android-fragments


【解决方案1】:

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

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

 private SomeInterface blah;

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

(3) 在FragmentActivity 中实现接口。

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

【讨论】:

  • 父本身是Fragment而不是FragmentActivity,所以我不能使用onAttach,而是将它作为参数传递给子Fragment的构造函数
  • 好吧——不过你仍然可以使用界面。这比静态引用要好。我的另一个想法是使用您从父级访问的内部抽象类。这样你就可以用这种方式回调主机片段。有点类似的概念。
  • 接口是面向对象编程的重要组成部分。为什么会有这么多问题?
  • 我想问问提出这个问题的人
【解决方案2】:

为了在较旧(和较新)版本中获取父片段,我找到了一种解决方法:

1) 在您的活动中设置 ParentFragment 的标签(通过 .add() 或 .replace())。查看下面的链接了解更多信息,或第 2 步了解 ParentFragment 中的类似示例: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 中包含了 ParentFragment,您可以在需要时使用它,所以您在哪里使用它:

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

【讨论】:

    【解决方案3】:

    【讨论】:

    • 哦,太好了,这真的很有帮助。 api 名称相同,getParentFragment() 所以有混乱,认为......这个功能对于 API
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 2017-03-27
    • 2016-12-17
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2016-04-03
    • 2016-04-14
    相关资源
    最近更新 更多