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()
}
}
}
这里有一些问题。
您应该在 onCreate()
中设置您的内容视图,而不是 onStart()
。 onStart()
可以为同一个 Activity
实例调用多次。例如,如果您启动 Activity
,按主页按钮,然后恢复您的应用程序,您将经历 onPause()
、onStop()
、onStart()
、onResume()
。您只需要在创建 Activity
时初始化您的视图。
您显示 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)
}
为什么我的片段 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()
}
}
}
这里有一些问题。
您应该在
onCreate()
中设置您的内容视图,而不是onStart()
。onStart()
可以为同一个Activity
实例调用多次。例如,如果您启动Activity
,按主页按钮,然后恢复您的应用程序,您将经历onPause()
、onStop()
、onStart()
、onResume()
。您只需要在创建Activity
时初始化您的视图。您显示
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)
}