简体   繁体   English

savedInstanceState无法正确还原Fragment

[英]savedInstanceState not restoring Fragment properly

Why is it that my fragment returns a blank screen whenever I use savedInstanceState with it? 为什么每当我将savedInstanceState与片段一起使用时,片段都会返回黑屏? I've already included the relevant savedInstanceState code in my activity, but the associated fragment still doesn't appear at all. 我已经在活动中包含了相关的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()
        }
    }
}

There are a few problems here. 这里有一些问题。

  1. You should be setting your content view in onCreate() , not onStart() . 您应该在onCreate()而不是onStart()设置内容视图。 onStart() can be invoked multiple times for the same Activity instance. 可以为同一Activity实例多次调用onStart() For instance, if you start your Activity , press the Home button, and then resume your app, you'll go through onPause() , onStop() , then onStart() , onResume() . 例如,如果您开始Activity ,按“主页”按钮,然后继续运行应用程序,则将经历onPause()onStop()onStart()onResume() You only need to initialize your view when the Activity is created. 创建Activity只需初始化视图。

  2. Your logic to display the Fragment only executes if the Activity is being recreated . 仅当重新创建 Activity才执行显示Fragment逻辑。 I think you likely meant the inverse. 我认为您可能是相​​反的意思。 You could simply change that to be if (!activityRecreated) but I would instead suggest cleaning this up by moving your view initialization entirely into onCreate() like so, and only checking if the theme state has changed in onStart() : 您可以简单地将其更改为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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM