[英]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. 这里有一些问题。
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
只需初始化视图。
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.