savedInstanceState在片段中始终为null

时间:2014-01-29 09:26:27

标签: android android-fragments fragment android-fragmentactivity

以下是我的代码:

public class MyListFragmentActivity extends FragmentActivity{

@Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    System.out.println("DEBUG : MLFA onCreate");
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction().replace(fragmentID, new MyListFragment())
            .replace(detailFragmentID, new MyDetailFragment()).commit();
        }
    }



     @Override
    protected void onRestart() {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            Fragment prevFrag = getSupportFragmentManager().findFragmentById(detailFragmentID);
    if (prevFrag != null) {
        fragmentTransaction.remove(prevFrag);
        getSupportFragmentManager().beginTransaction().replace(detailFragmentID, new MyDetailFragment()).commitAllowingStateLoss();
    } else {
        getSupportFragmentManager().beginTransaction().replace(detailFragmentID, new MyDetailFragment()).commitAllowingStateLoss();
    }
}

MyListFragment

public class MyListFragment extends Fragment{

//When we click on each item in list view call detail fragment to relad its layout
OnItemClickListener onItemClickListener = new OnItemClickListener() {

/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        /** Getting the existing detailed fragment object, if it already exists.
        *  The fragment object is retrieved by its tag name
        * */
        Fragment prevFrag = getFragmentManager().findFragmentById(detailFragmentID);

        /** Remove the existing detailed fragment object if it exists */
        if (prevFrag != null) {
            fragmentTransaction.remove(prevFrag);
           MyDetailFragment mydetailFragment = new MyDetailFragment();
            fragmentTransaction.replace(detailFragmentID, mydetailFragment);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.show(getFragmentManager().findFragmentById(detailFragmentID));
            fragmentTransaction.commit();
        }
}

MyDetailFragment

public class MyDetailFragment extends Fragment{

@Override
public void onCreate(Bundle savedInstanceState) {
 setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  if (savedInstanceState != null) {
    // it is not entering the inside here 
}

@Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
        // saving some values
    }

当我在设置setRetainInstance(true);后设置我的设备时,savedInstanceState始终为null,那么如何在此处获取保存的值?

为什么这样?我在这里做错了什么以及如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为你失去了你的instanceState,因为你总是在你的onRestart()方法中创建一个新的Fragment实例。

以这种方式尝试:

@Override
protected void onRestart() {
    Fragment prevFrag = getSupportFragmentManager().findFragmentById(detailFragmentID);
    if (prevFrag == null || !(prevFrag instanceof MyDetailFragment)) {
        getSupportFragmentManager().beginTransaction().replace(detailFragmentID, new MyDetailFragment());
    }
}

这样,只有在没有相同类型的其他有效片段的情况下,才会附加片段的新实例。

注意setRetainInstance(true);当配置发生更改时,会阻止FragmentManager销毁Fragment实例。 因此,手动销毁Fragment(通过调用.remove(...))然后使用.replace(...,new MyDetailFragment())初始化它是没有意义的。这就是为什么你总是得到一个空的savedInstanceState:你在一个新的实例,所以没有以前保存的状态!

还要记住,在FragmentTransaction上调用.commitAllowingStateLoss()允许片段管理器避免保存savedInstanceState,所以只有在你真正知道自己在做什么的时候才应该使用它。

祝你有愉快的一天! :)

答案 1 :(得分:0)

根据Android:

默认情况下,对于视图,

onSaveInstanceState()将被调用,并且只有它具有id。

默认实现通过在具有id的层次结构中的每个视图上调用onSaveInstanceState()并保存当前焦点视图的id(所有这些都是由onRestoreInstanceState(Bundle)的默认实现恢复。