savedInstanceState 没有正确恢复 Fragment

savedInstanceState not restoring Fragment properly

为什么我的片段 returns 每次使用 savedInstanceState 时都是空白屏幕?我已经在我的 activity 中包含了相关的 savedInstanceState 代码,但是相关的片段仍然根本没有出现。

class MyActivity : AppCompatActivity() {
    private var mCurrentValue: Boolean = false

    private var mTwoPane: Boolean = false

    private var activityRecreated: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        mCurrentValue = mSharedPreferences.getBoolean("preference_a", false)
        when {
            mCurrentValue -> setTheme(R.style.MyDarkTheme)
            else -> setTheme(R.style.MyLightTheme)
        }

        super.onCreate(savedInstanceState)

        activityRecreated = savedInstanceState != null

        setContentView(R.layout.md)
    }

    override fun onStart() {
        super.onStart()

        setContentView(R.layout.md)

        mTwoPane = findViewById<View>(R.id.detail_container) != null

        val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val mNewValue = mSharedPreferences.getBoolean("preference_a", false)
        when {
            mCurrentValue != mNewValue -> recreate()
        }

        val mToolbar = findViewById<Toolbar>(R.id.my_toolbar)
        setSupportActionBar(mToolbar) 

        if (activityRecreated) {
            val newFragment = MyFragment()
            val transaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.master_container, newFragment)
            transaction.commit()
        }
    }
}

这里有一些问题。

  1. 您应该在 onCreate() 中设置您的内容视图,而不是 onStart()onStart() 可以为同一个 Activity 实例调用多次。例如,如果您启动 Activity,按主页按钮,然后恢复您的应用程序,您将经历 onPause()onStop()onStart()onResume()。您只需要在创建 Activity 时初始化您的视图。

  2. 您显示 Fragment 的逻辑仅在 Activity 正在 重新创建 时执行。我想你的意思可能是相反的。您可以简单地将其更改为 if (!activityRecreated),但我建议您通过将视图初始化完全移至 onCreate() 来清理它,并且仅检查主题状态是否已在 onStart() 中更改:


class MyActivity : AppCompatActivity() {
    private val useDarkTheme: Boolean = false
    private var twoPane: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        useDarkTheme = shouldUseDarkTheme()
        setTheme(if (useDarkTheme) R.style.MyDarkTheme else R.style.MyLightTheme)

        super.onCreate(savedInstanceState)
        setContentView(R.layout.md)

        // savedInstanceState will be null only the first time the Activity is created
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.master_container, MyFragment())
                .commit()
        }

        twoPane = findViewById<View>(R.id.detail_container) != null
        setSupportActionBar(findViewById(R.id.my_toolbar))
    }

    override fun onStart() {
        super.onStart()

        if (useDarkTheme != shouldUseDarkTheme()) {
            recreate()
        }
    }

    private fun shouldUseDarkTheme(): Boolean = 
        PreferenceManager.getDefaultSharedPreferences(this).getBoolean("preference_a", false)
}