Почему Fragmenttransaction replace () действует как add ()? - PullRequest
0 голосов
/ 16 мая 2019

У меня есть здесь пример проекта GitHub . Это просто действие, надувающее другие фрагменты в нем, нажав на нижние вкладки:

  1. Аплодисменты раздувают Фрагмент 1
  2. Нажатие 1.Tab -> надувает фрагмент 1
  3. Нажатие 2.Tab -> надувает Фрагмент 2
  4. Нажатие 3.Tab -> надувает фрагмент 3

и все используемые с помощью this.supportFragmentManager?.beginTransaction()?.replace(). Для меня это действует как FragmentTransaction.add (), потому что:

Когда я запускаю приложение (фрагмент 1 загружен) и нажимаю

  • 2-я вкладка для фрагмента 2 (Фрагмент тоста 2)
  • и 3-я вкладка для фрагмента 3 (Фрагмент тоста 3)
  • затем кнопка (Тост Frag 2)
  • снова кнопка (Тост Frag 1)

Весь стек работает обратно. Таким образом, ничего не было " заменено ", все было добавлено ?

Всякий раз, когда я нажимаю назад, я хотел бы загрузить «Фрагмент 1», который является начальным Фрагментом для действия. Как?

1 Ответ

0 голосов
/ 16 мая 2019

Полагаю, это происходит потому, что фрагменты заменяются, но они также добавляются в BackStack следующим образом:

BaseActivity.kt

// Note the .addToBackStack(null)
this.supportFragmentManager?.beginTransaction()?.replace(resId, newFragment)?.addToBackStack(null)?.commit()

Из документации для addToBackStack

Добавьте эту транзакцию в задний стек.Это означает, что транзакция будет запомнена после того, как она будет зафиксирована, и обратится к своей операции, когда позднее будет извлечена из стека.

Вы можете проверить этот вопрос , чтобы проверить большеинформация о разнице между add, replace и addToBackStack.

Если вы не хотите «запоминать и восстанавливать» переход фрагмента, просто удалите вызов на addToBackStack.

Редактировать

Если вы всегда хотите вернуться к первому фрагменту, вы можете сделать:

Сохранить addToBackStack().Таким образом, история навигации будет сохранена

this.supportFragmentManager?.beginTransaction()?.replace(resId, 

newFragment)?. AddToBackStack (null) ?. commit ()

Переопределить onBackPressed на MainActivity или BaseActivity и запроситьчтобы всегда возвращаться к первой транзакции:

override fun onBackPressed() {
    if(this.supportFragmentManager?.getBackStackEntryCount() > 0) {
        this.supportFragmentManager?.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    } else {
       super.onBackPressed()
    }
}

Просто обратите внимание, что это тестовый код, и я не смог проверить.Кроме того, я не знаком с Kotlin.Итак, это был лучший код из всех, что я мог получить ... Протестируйте и дайте мне знать результат ... В любом случае вы можете получить ideia.

Другой вариант:

УдалитьaddToBackStack():

this.supportFragmentManager?.beginTransaction()?.replace(resId, newFragment)?.addToBackStack(null)?.commit()

Затем необходимо вручную указать, какой фрагмент должен отображаться, когда пользователь нажимает клавишу возврата ... что-то вроде:

private var int : mCurrentFragment = 1

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    when (item.itemId) {
        R.id.navigation_home -> {
            mCurrentFragment = 1
            ...
        }
        R.id.navigation_dashboard -> {
            mCurrentFragment = 2
            ...
        }
        R.id.navigation_notifications -> {
            mCurrentFragment = 3
            ...
        }
    }
    false
}

override fun onBackPressed() {
    if(mCurrentFragment != 1) {
        replaceFragment(R.id.container_main_layout, Fragment1())
    } else {
       super.onBackPressed()
    }
}
...