【问题标题】:getSupportFragmentManager().findFragmentByTag unpredictable behaviourgetSupportFragmentManager().findFragmentByTag 不可预知的行为
【发布时间】:2013-11-26 00:13:22
【问题描述】:

如果我像这样向我的活动添加片段:

    fragment_tags = new ArrayList<String>();
    fragment_tags.add("user_fragment");
    fragment_tags.add("memorial_fragment");

    UserFragment user = new UserFragment();
    MemorialFragment memorial = new MemorialFragment();

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    ft.add(R.id.content_frame, user, fragment_tags.get(0));
    ft.add(R.id.content_frame, memorial, fragment_tags.get(1));
    ft.commit();

然后过了一段时间,我尝试像这样检索这些片段:

    List<Fragment> frg = getSupportFragmentManager().getFragments();
    Fragment fragUser = getSupportFragmentManager().findFragmentByTag(
            "user_fragment");
    Fragment fragUserID = getSupportFragmentManager().findFragmentById(
            R.id.user_fragment_id);
            Log.d("MV", "fragments size:" + (frg == null ? " null" : frg.size()));

Log.d 将始终返回大小为 2,但 fragUser 有时为 null,有时它是我放入事务中的片段。

比较有意思的是这段代码:

    try {
        Log.d("MV", "0:" + frg.get(0).toString());
        Log.d("MV", "1:" + frg.get(1).toString());
    } catch (NullPointerException e) {
        Log.d("MV", "null caught");
    }

有时适用于两个片段,有时只适用于第一个片段,如果我这样做:

if(frg.get(0) == fragUser)

它有时会被评估为真实,但不经常..我不太了解这种行为,但我需要实现多个片段之间的切换,所以我需要获取对确切片段的引用。有人吗?我现在尝试解决这个问题 6 个小时,但我真的不明白该怎么做。谢谢

【问题讨论】:

  • 好吧回答一部分... "if(frg.get(0) == fragUser)" ...你不能使用==比较对象.您需要使用if(frg.get(0).equals(fragUser))
  • Squonk 实际上这是我的意图.. 我不在乎对象是否具有相同的属性,但如果它们的引用相同,它们必须是相同的对象.. 我想要相同的片段。

标签: android android-fragments fragmentmanager


【解决方案1】:

由于这个问题是我在 2013 年发布的,获得了超过 1000 次浏览,但仍然没有任何回应,我将尝试总结这些年来我在处理片段时所学到的东西。

  1. 不要使用 getSupportFragmentManager().getFragments()(更多信息请参见 getSupportFragmentManager().getFragments() shows a compile time error
  2. FragmentManager 用于管理片段生命周期。不要试图将片段放入您自己的列表中或保持对它们的强引用
  3. if(frg.get(0) == fragUser) 无法始终工作的原因与第 2 点有关。- FragmentManager 管理片段,因此当它决定杀死一个片段并重新创建它时,引用将不匹配。

现在的问题是 - 如何安全地使用片段?

  1. 使用 setArguments() 方法将数据传递到包中的片段,以便 Android 可以终止并重新创建片段。
  2. FragmentManager.findFragmentById(R.id.some_id) 将找到附加到带有 id some_id 的视图的片段。如果您将多个片段添加到 R.id.some_id 中,FragmentManager.findFragmentById(R.id.some_id) 很可能会给出不同的结果(但它通常是找出当前可见的片段的好方法,除非您还隐藏/显示您的片段)
  3. 了解 FragmentTransaction API 的不同方法,尤其是 addreplacehidedetachremoveshow 之间的区别。
  4. 有时事情只是不起作用(当多个片段过渡动画同时运行时崩溃)或者您的应用程序不是片段的良好用例。您可以在经典帖子https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97 中阅读更多关于后者的信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2018-09-03
    相关资源
    最近更新 更多