Свойство Lateinit не было инициализировано во фрагменте onSaveInstanceState - PullRequest
0 голосов
/ 24 октября 2019

У меня есть действие, которое построено из фрагментов. Теперь я хочу сохранить некоторые данные некоторых виджетов в onSaveInstanceState. Я постараюсь подвести итог ситуации.

Это моя деятельность:

Activity.kt:

class Activity: AppCompatActivity() {

    private lateinit var fragment1: Fragment1
    private lateinit var fragment2: Fragment2
    private lateinit var fragment3: Fragment3

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        setContentView(R.layout.activity)

        if(savedInstanceState != null) {
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment1") != null)
                fragment1 = supportFragmentManager.getFragment(savedInstanceState, "fragment1") as Fragment1
            else fragment1 = Fragment1()
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment2") != null)
                fragment2 = supportFragmentManager.getFragment(savedInstanceState, "fragment2") as Fragment2
            else fragment2 = Fragment2()
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment3") != null)
                fragment3 = supportFragmentManager.getFragment(savedInstanceState, "fragment3") as Fragment3
            else fragment3 = Fragment3()
        } else {
            fragment1 = Fragment1()
            fragment2 = Fragment2()
            fragment3 = Fragment3()

            supportFragmentManager
                .beginTransaction()
                .add(R.id.content_frame, fragment1)
                .commit()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        if(fragment1.isAdded)
            supportFragmentManager.putFragment(outState, "fragment1", fragment1)
        if(fragment2.isAdded)
            supportFragmentManager.putFragment(outState, "fragment2", fragment2)
        if(fragment3.isAdded)
            supportFragmentManager.putFragment(outState, "fragment3", fragment3)
    }

    fun addFragment2() {
        supportFragmentManager
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.content_frame, fragment2)
            .commit()
    }

    fun addFragment3() {
        supportFragmentManager
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.content_frame, fragment3)
            .commit()
    }
}

Это реализация фрагментов.

Fragment2:

Fragment2.kt:

class Fragment2: Fragment() {

    private lateinit var customView: CustomView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment2, container, false)

        customView = view.findViewById(R.id.custom_view)
        if(savedInstanceState != null) {
            customView.setIntValue(savedInstanceState.getInt("int_value"))
        }

        return view
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("int_value", customView.intValue)
    }
}

Это фрагмент2. Итак, сейчас ситуация следующая. Я звоню addFragment2() и addFragment3(). Теперь я перехожу в ландшафт. Вызваны следующие методы обратного вызова:

  1. onSaveInstanceState в Деятельности
  2. onSaveInstanceState во Фрагменте 3
  3. onSaveInstanceState во Фрагменте2
  4. onSaveInstanceState во фрагменте 1
  5. onCreate в действии
  6. onCreate во фрагменте3
  7. onCreateView во фрагменте3
  8. onCreate вFragment2
  9. onCreate во Fragment1 *

Во Fragment2 и Fragment 1 onCreateView не вызывается, поскольку фрагменты не видны.

Теперь япоменять на портрет снова. Методы обратного вызова вызываются снова. Но теперь, во Fragment2, я получаю исключение: lateinit property customView is not initialized. (При вызове customView.intValue в onSaveInstanceState) Я думаю, что это не имеет значения, если это пользовательский виджет или нет, исключение также будет выброшено с использованием только TextView.

Это делаетсмысл для меня. В onSaveInstanceState в Activity fragment2.isAdded != null равно false, поэтому фрагмент не сохраняется в outState и снова создается в onCreate. Тогда onCreateView во Fragment2 не вызывается, поэтому customView не инициализируется. Теперь, когда вызывается onSaveInstanceState во Fragment2, вызов customView вызывает исключение.

Итак, я понимаю, почему это не работает, но я понятия не имею, как заставить его работать. Фрагменты реализованы и сохранены неправильно? Есть ли способ, чтобы все экземпляры фрагментов были сохранены, а не только тот, который в данный момент находится вверху?

Код является лишь примером, который должен подвести итог моей проблемы. Если вам нужно больше кода, я могу отредактировать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...