可以仅使用一个实例创建片段

时间:2013-06-17 18:31:48

标签: android android-fragments fragment android-fragmentactivity

我只是想知道,片段创建只能有一个实例还是单例? 我也经历了 Google iosched 项目。他们只是创建

Fragment a = new Fragment();

每当他们想要......

假设例如:

public static FragmentManager instance;

    public static FragmentManager getInstance() {
        if (instance == null) {
            instance = new FragmentManager();
        }
        return instance;
    }

    public TestFragment getTestFragment() {
        if (testFragment == null) {
            testFragment = new TestFragment ();
        }

        return  testFragment 
    }
}

我可以随处使用吗? 交易FragmentManager.getInstance().getTestFragment()

例如:

getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.content_frame, FragmentManager.getInstance().getTestFragment())
    .commit();

或OS会自动销毁参考或与之相关的一些问题吗?

3 个答案:

答案 0 :(得分:3)

当您使用getSupportFragmentManager().beginTransaction().replace时,您可以添加第三个参数作为可用作标记的字符串,因此,如果您想恢复以前的片段,可以使用getSupportFragmentManager().findFragmentByTag(String)以便赢得'必须创建一个新的片段。

所以就像这样

使用findFragmentByTag(String)检查片段是否存在(如果不存在),创建一个新片段并调用getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame,myFragment,myTag).commit();,其中myTag是您将在findFragmentByTag中使用的字符串。这样您就不会创建每种类型的多个片段。

我希望它有道理:)

有关详情,请查看thisthis

答案 1 :(得分:2)

没有这样的限制。但是,两个片段对象不能具有相同的标记或id。

此外,重新附加现有片段非常有用,而不是创建新片段。

MyFragment f = (MyFragment) getFragmentManager().findFragmenByTag("my_fragment");

if(f == null){
  f = Fragment.instantiate(context, MyFragment.class.getName());
}

if(!f.isAdded()){
  //--do a fragment transaction to add fragment to activity, WITH UNIQUE TAG--
  //--Optionally, add this transaction to back-stack as well--
}

答案 2 :(得分:0)

如果您尝试确保不会使用相同的“类型”两次或更多次添加或替换一个或多个片段,那么您可以使用FragmentManager.BackStackEntry来了解哪些片段是目前位于堆栈顶部。

String TAG_FIRST_FRAGMENT = "com.example.name.FIRST.tag";
String TAG_SECOND_FRAGMENT = "com.example.name.SECOND.tag";

FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() == 0 || 
    !fragmentManager.getBackStackEntryAt(
        fragmentManager.getBackStackEntryCount() - 1)
    .getName().equals(TAG_SECOND_FRAGMENT)) {
//Now it's safe to add the secondFragment instance

FragmentTransaction transaction = fragmentManager.beginTransaction();
//Hide the first fragment if you're sure this is the one on top of the stack 
transaction.hide(getSupportFragmentManager().findFragmentByTag(TAG_FIRST_FRAGMENT));
SecondFragment secondFragment = new SecondFragment();
transaction.add(R.id.content_frame, secondFragment, TAG_SECOND_FRAGMENT);
//Add it to back stack so that you can press back once to return to the FirstFragment, and
//to make sure not to add it more than once.
transaction.addToBackStack(TAG_SECOND_FRAGMENT);
transaction.commit();

}