【问题标题】:Where Fragment save its State when FragmentTransaction.Replace?FragmentTransaction.Replace 时,Fragment 在哪里保存其状态?
【发布时间】:2013-04-07 04:27:56
【问题描述】:

背景:左边有一个菜单,右边有不同的可滚动内容。我想保存滚动位置。但我失败了。那么……

我已经建立了一个非常简单的项目来测试它。

换句话说,我在左边有一个菜单,不同的内容在右边都有一个<EditText>。 (虽然属于同一类,但它们属于不同的实例)

在代码中,(非常简单)

content.xml

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Please save my text ..." />

ContentFragment.java

package ... import ...

public class ContentFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.content, container, false);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        System.out.println("Why this is NOT called ?");
        Log.v("onSaveInstanceState()", "outState = " + outState);
    }
}

程序生成MenuFragment.java

package ... import ...

public class MenuFragment extends ListFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new String[]{"Item 1", "Item 2", "Item 3"}));
    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        ((MainActivity) getActivity()).click();
    }
}

最后,我们的 MainActivity.java

package ... import ...

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null)
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.menu, new MenuFragment()).commit();
    }
    public void click() {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.content, new ContentFragment()  // everytime load a new instance
                ).addToBackStack(null).commit();
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        System.out.println("... and this is NOT called neither :-/");
        Log.v("onSaveInstanceState()", "outState = " + outState);
    }
}

要测试它,请不要旋转您的设备。

首先,从菜单中选择一个项目,然后在文本框中输入内容。然后选择另一个项目并再次键入内容。重复几次。然后返回并...

您会发现您之前输入的文本已保存!!!

文本被保存并不奇怪......

但是 很惊讶,文本被保存 所有的 onSaveInstanceState() 函数都没有被调用。

Android 何时在replaced by FragmentTransaction 时保存它们?

如果我想在每个Fragment 实例中额外保存一些数据(比如滚动位置),我应该把我的代码放在哪里?

【问题讨论】:

  • 另外,我发现Fragment.onSaveInstanceState()中的Bundle总是null(即使屏幕旋转,或称为FragmentManager.saveFragmentInstanceState())。这对我来说很奇怪。你能解释一下吗?
  • 有了source codes,就解决了:)

标签: android android-layout android-fragments android-fragmentactivity fragmenttransaction


【解决方案1】:

默认情况下,Edittext 保存自己的实例。请参阅 Yalla T. 的回答。

How to retain EditText data on orientation change?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 2021-09-27
    • 2013-12-06
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多