Activity和Fragment中的自动UI配置更改处理有时会失败

Cil*_*nco 8 android android-lifecycle android-fragments android-activity

我已经写了很长时间的Android应用程序,但现在我遇到了一个我从未想过的问题.这是关于Android的生命周期Activitys,并Fragments在有关的配置更改.为此,我用这个必要的代码创建了一个小应用程序:

public class MainActivity extends FragmentActivity {

    private final String TAG = "TestFragment";
    private TestFragment fragment;

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

        FragmentManager fm = getSupportFragmentManager();
        fragment = (TestFragment) fm.findFragmentByTag(TAG);

        if (fragment == null) {
            fragment = new TestFragment();
            fm.beginTransaction().add(R.id.fragment_container, fragment, TAG).commit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的代码TestFragment.需要注意的是我打电话setRetainInstance(true);onCreate方法,这样的片段没有在配置更改后recrated.

public class TestFragment extends Fragment implements View.OnClickListener {

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

    @Override
    public View onCreateView(LayoutInflater li, ViewGroup parent, Bundle bundle) {
        View rootView = li.inflate(R.layout.fragment_test, parent, false);
        Button button = (Button) rootView.findViewById(R.id.toggleButton);

        button.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v) {
        Button button = (Button) v;
        String enable = getString(R.string.enable);

        if(button.getText().toString().equals(enable)) {
            button.setText(getString(R.string.disable));
        } else {
            button.setText(enable);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的片段使用的布局:

<LinearLayout
    ...>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/toggleButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/enable"/>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我将设备的文本Button转换回默认值.当然ViewFragment是新创建并充气,但对于浏览保存的情况下应恢复.EditText我的布局中也有一个,旋转后文本和其他属性仍然存在.那么为什么Button没有Bundle默认恢复?我在开发者网站上看过:

默认情况下,系统使用Bundle实例状态来保存活动布局中每个View对象的信息(例如输入EditText对象的文本值).因此,如果您的活动实例被销毁并重新创建,则布局的状态将恢复到之前的状态,而您无需代码.

在过去的几天里我也读过很多答案,但我不知道他们的实际情况如何.请不要留下评论或答案android:configChanges=...这是非常糟糕的做法.我希望有人可以为我缺乏理解带来光明.

Mat*_*Bos 5

您应该保存片段的状态onSaveInstanceState(Bundle outState)并在onViewCreated(View view, Bundle savedState)方法中恢复它.这样,您最终将获得UI,就像配置更改之前一样.