getSupportFragmentManager()。findFragmentByTag不可预测的行为

时间:2013-11-26 00:13:22

标签: android android-fragments fragmentmanager

如果我在这样的活动中添加片段:

    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个小时,我真的不明白该怎么做。谢谢

1 个答案:

答案 0 :(得分:0)

由于我在2013年发布了这个问题,获得了超过1000个观点,但仍然没有任何回应,我将总结我多年来在处理片段时所学到的知识。

  1. 不要使用getSupportFragmentManager()。getFragments()(getSupportFragmentManager().getFragments() shows a compile time error中有更多内容)
  2. FragmentManager用于管理片段生命周期。不要试图将片段放入您自己的列表中或保持对它们的强引用
  3. if(frg.get(0) == fragUser)不能始终如一地工作的原因与第2点相关联。 - FragmentManager管理片段,因此当它决定杀死一个并再次重新创建它时,引用将不匹配。
  4. 现在的问题是 - 如何安全地处理碎片?

    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之间的差异。< / LI>
    4. 有时事情不起作用(当多个片段转换动画一次运行时崩溃)或者您的应用程序不是片段的好用例。您可以在现在的经典帖子https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97
    5. 中详细了解后者