为什么fragmentManager.findFragmentByTag全部返回null?

时间:2015-10-08 20:15:42

标签: android android-fragments

膨胀视图是昂贵的,所以我正在尝试重用我的片段,这些片段是在选择相关的导航抽屉项目时启动的。读了一下之后,常见的方法似乎是使用tag参数调用FragmentTransition.replace方法,然后在需要时再次使用findFragmentByTag方法。

现在我的问题是,findFragmentByTag ALLWAYS返回null。我知道它是否因为GC而有时无效,但它总是空的似乎对我来说有点不对。所以我的源代码一定有问题。

我发现许多人都有同样问题的线程,但是解决方案是在替换调用中添加标记,或者在replace或findFragmentByTag调用中添加标记中的一些拼写错误。可悲的是,两者都不是手头的问题。

onNavigationDrawerItemSelected是mainactivity中唯一的方法,它以任何方式触及Fragments。它会在Navigationdrawer的onCreate中调用,以便应用程序从Map_Fragment开始。

@Override
public void onNavigationDrawerItemSelected(int position) {
    String method = "MainActivity.onNavigationDrawerItemSelected";
    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment replacerFragment = null;

    String usedTag = "";
    switch(position){
        case 0:
            usedTag = Map_Fragment.FRAGMENT_TAG; //which is "MAP_FRAGMENT"
            replacerFragment = fragmentManager.findFragmentByTag(usedTag);
            if(replacerFragment == null){
                replacerFragment = Map_Fragment.newInstance();
            }
            break;
        case 1:
            usedTag = Setting_Fragment.FRAGMENT_TAG; //which is "SETTING_FRAGMENT"
            replacerFragment = fragmentManager.findFragmentByTag(usedTag);
            if(replacerFragment == null){
                replacerFragment = Setting_Fragment.newInstance();
            }
            break;
    }

    Log.i(method, "usedTag: " + usedTag); //prints the correct tag
    if(replacerFragment != null) {
        fragmentManager.beginTransaction().replace(R.id.container, replacerFragment, usedTag).commit();
    }
}

目前的片段是:

public class Setting_Fragment extends Fragment {
    public final static String FRAGMENT_TAG = "SETTING_FRAGMENT";

    public static Setting_Fragment newInstance() {
        Log.i("Setting_Fragment.newInstance", "boing");
        Setting_Fragment fragment = new Setting_Fragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        ((MainActivity) activity).onSectionAttached(getString(R.string.fragment_title_settings)); //changes the Title of the Activity
    }
}

1 个答案:

答案 0 :(得分:1)

在提交之前,您必须将行addToBackStack(null)添加到FragmentTransaction中。这使得当从视图中移除前一个片段时,它将被停止而不会被破坏。

这在docs here

中说明
  

注意:当您删除或替换片段并将事务添加到后台堆栈时,将删除已删除的片段   (没有销毁)。如果用户导航回来恢复片段,   它重新启动。如果您不将事务添加到后台堆栈,那么   拆除或更换时,碎片会被破坏。