【问题标题】:savedInstanceState is always null in fragmentssavedInstanceState 在片段中始终为 null
【发布时间】:2014-02-21 00:10:50
【问题描述】:

下面是我的代码:

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,那么我如何才能在此处获取我保存的值?

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

【问题讨论】:

    标签: android android-fragments fragment android-fragmentactivity


    【解决方案1】:

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

    试试这个方法:

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

    这样,只有在没有另一个相同类型的有效 Fragment 时,您才附加一个新的 Fragment 实例。

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

    还请记住,在 FragmentTransaction 上调用 .commitAllowingStateLoss() 可以让 Fragment Manager 避免保存 savedInstanceState,因此只有在您真正知道自己在做什么时才应该使用它。

    祝你有美好的一天! :)

    【讨论】:

      【解决方案2】:

      根据安卓:

      onSaveInstanceState() 将默认为视图调用,当且仅它有一个 id。

      默认实现会为您处理大部分 UI 实例状态,方法是在层次结构中具有 id 的每个视图上调用 onSaveInstanceState(),并保存当前聚焦视图的 id(所有这些都是由 onRestoreInstanceState(Bundle)) 的默认实现恢复。

      【讨论】:

        猜你喜欢
        • 2013-12-31
        • 1970-01-01
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多