Fragment中的savedInstanceState不起作用

时间:2016-06-21 20:09:23

标签: android android-fragments

我的savedInstanceState出错了我的片段。

保存实例不起作用。当我切换回“HomeMenu”时,所有字段都会消失。

关于我的活动:

 private void selectItemFromDrawer(int position) {
    FragmentManager fragmentManager = getFragmentManager();

    Fragment fragment = null;
    String tagFrag = "default";
    switch (mNavItems.get(position).mTitle) {

        case R.string.menu_home:
            fragment = fragmentManager.findFragmentByTag("menu_home");

            if(fragment == null) {
                fragment = new HomeMenuFragment();
            } else {
                Toast.makeText(customActivity.this, "already Exists", Toast.LENGTH_SHORT).show();
            }
            tagFrag = "menu_home";
            break;
        case R.string.menu_pref:
            fragment = fragmentManager.findFragmentByTag("menu_pref");
            if(fragment == null)
                fragment = new PreferencesFragment();

            tagFrag = "menu_pref";
            break;
    }
    if(fragment != null) {
        fragmentManager.beginTransaction()
                .replace(R.id.mainContent, fragment, tagFrag)
                .commit();
    }
}

多数民众赞成有效..片段正确改变..

仅当片段处于​​活动状态时,TOAST才有效..但如果我切换回他,则无效。

示例:

  1. Home => Home => “toast Appear”
  2. Home => Pref => Home => “没有吐司”。
  3. 进入我的HomeMenuFragment我使用此代码:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.activity_main, container, false);
    }
    
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            strUser = savedInstanceState.getString("strUser", "");
            strName = savedInstanceState.getString("strName", "");
            strDesc = savedInstanceState.getString("strDesc", "");
    
            if(((TextView) getActivity().findViewById(R.id.user))!=null)
                ((TextView) getActivity().findViewById(R.id.user)).setText(strUser);
    
            if(((TextView) getActivity().findViewById(R.id.name))!=null)
                ((TextView) getActivity().findViewById(R.id.name)).setText(strName);
            if(((TextView) getActivity().findViewById(R.id.desc))!=null)
                ((TextView) getActivity().findViewById(R.id.desc)).setText(strDesc);
    
        }
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("strUser", ((TextView) getActivity().findViewById(R.id.user)).getText().toString());
        outState.putString("strName", ((TextView) getActivity().findViewById(R.id.name)).getText().toString());
        outState.putString("strDesc", ((TextView) getActivity().findViewById(R.id.desc)).getText().toString());
    }
    

3 个答案:

答案 0 :(得分:0)

好的,我会尝试解释一下,这并不容易。

在这种情况下,您的片段不会被破坏,只有其中的视图可以。 因此,您使用的每个视图都必须实现状态保存/恢复。

我给你留下了更好的解释,希望这对你有所帮助! https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en

<强>更新

尝试使用newIstance创建片段,这是避免参数丢失的最佳做法。 例如:

public static MyFragment newInstance(String user, String name, String desc) {
    MyFragment mFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putString("user", user);
    args.putString("name", name);
    args.putString("desc", desc);
    mFragment.setArguments(args);

    return mFragment;
}

在片段onCreate()中,您可以使用以下方式访问数据:

String strUser = getArguments().getString("user", "");

如果片段是由Android重新创建的,则Bundle将可用。 请记住,只能在将片段附加到活动之前调用setArguments。

让我知道!

答案 1 :(得分:0)

根据Bundle文档,没有putString()getString()方法,您需要使用putStringArrayList (String key, ArrayList<String> value)。我还建议你在getActivity()。findViewById()上避免这么多调用,众所周知它会导致很多开销。另外,为什么要从片段内的活动中获取视图值?看起来像重复的代码。无论如何,试试这个:

 TextView tvUser, tvName, tvDesc;

@Override
public void onCreate(Bundle savedInstanceState) {

    // Store TextView references calling findViewById only once
    tvUser =  ((TextView) getActivity().findViewById(R.id.user));
    tvName  = ((TextView) getActivity().findViewById(R.id.user));
    tvDesc = ((TextView) getActivity().findViewById(R.id.user));
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState != null) {
        ArrayList al = new ArrayList();
        al = savedInstanceState.getStringArrayList("args");
        tvUser.setText(al.get(0));
        tvName.setText(al.get(1));
        tvDesc.setText(al.get(2));
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    ArrayList al = new ArrayList();
    al.add(0, tvUser.getText());
    al.add(1, tvName.getText());
    al.add(2, tvDesc.getText());
    outState.putStringArrayList("args", al);
}

答案 2 :(得分:-1)

可能是在放入希望保存的字符串之前调用super.onSaveInstanceState(outState)。要解决此问题,您只需拨打super.onSaveInstanceState(outState) AFTER 即可添加您希望保存的值。以下是您需要进行的更改:

@Override
public void onSaveInstanceState(Bundle outState) {    
    outState.putString("strUser", ((TextView) getActivity().findViewById(R.id.user)).getText().toString());
    outState.putString("strName", ((TextView) getActivity().findViewById(R.id.name)).getText().toString());
    outState.putString("strDesc", ((TextView) getActivity().findViewById(R.id.desc)).getText().toString());
    //moved it here
    super.onSaveInstanceState(outState);
}

我希望这能解决你的问题。试一试,让我知道。