saveInstanceState не восстанавливает фрагмент правильно - PullRequest
0 голосов
/ 20 декабря 2018

Почему мой фрагмент возвращает пустой экран всякий раз, когда я использую savedInstanceState с ним?Я уже включил соответствующий код 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 Ответ

0 голосов
/ 21 декабря 2018

Здесь есть несколько проблем.

  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)
}
...