Как сохранить состояние экземпляра фрагмента после использования replace ()?

1

Моя активность имеет 3 дочерних фрагмента - только один из них отображается одновременно. Я использую BottomNavigationView для переключения между дочерними фрагментами. Показанный начальный дочерний фрагмент, GameFragment(), раздувается, когда действие создается с помощью supportFragmentManager.beginTransaction().replace() который заменяет контейнер фрагмента в моем XML.

Во-первых, позвольте мне показать вам полный жизненный цикл моего вхождения в свою деятельность, переключения фрагмента на replace(), а затем переключения на первоначальный фрагмент на replace(). Эти операторы журнала относятся только к Деятельности и Фрагменту A (фрагмент B & C не показан).

onCreate (Activity)
onAttach (Fragment A)
onCreate (Fragment A)
onCreateView (Fragment A)
onActivityCreated (Fragment A)

.replace() Фрагмент A с Фрагментом B

onPause (Fragment A)
onStop (Fragment A)

.replace() Фрагмент B с Фрагментом A

onAttach (Fragment A)
onCreate (Fragment A)
onCreateView (Fragment A)
onActivityCreated (Fragment A)

Чтобы сохранить мое состояние фрагмента при переключении фрагментов с помощью replace(), я попробовал следующие методы, которые оба потерпели неудачу.

  1. Изменение значения переменной-члена во фрагменте в onDestroyView() и последующий доступ к нему в onActivityCreated()

  2. Добавление getArguments() в onDestroyView() и доступ в onActivityCreated().

    class GameFragment : Fragment(), View.OnClickListener {
    
        var truthisvisible = "string"
    
        override fun onDestroyView() {
            super.onDestroyView()
            truthisvisible = "stringafter"
            arguments?.putString("success", "success")
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(R.layout.fragment_game, container, false)
        }
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            Log.d("truthisvisible", truthisvisible) // prints "string"
            if (savedInstanceState != null){
                Log.d("LifecycleChange", "onActivityCreated savedInstanceState") // savedInstanceState is always null
            }
            super.onActivityCreated(savedInstanceState)
            Log.d("truthisvisible", truthisvisible) // prints "string"
            val print = arguments?.getString("success", "failure")
            Log.d("bool", "..." + print) // prints "...null"
    

Я также пытался изменить переменную truthisvisible в onPause(), а также пытался получить переменную в onCreateView() однако переменная никогда не меняется на stringafter. То же самое касается getArguments() - аргументы не меняются.

Кроме того, savedInstanceState во всех этих методах имеет значение null. Хотя я ожидаю, что onSaveInstanceState() никогда не запускается при замене фрагментов.

Я в полном тупике. Как изменить или сохранить переменную в моем фрагменте при вызове replace()? Вот моя родительская активность, если вам интересно:

var initialFragmentLoad = false

class TruthOrDare : FragmentActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        if (!initialFragmentLoad){
            return true
        }
        val selectedFragment = when (item.itemId){
            R.id.action_leaderboards -> LeaderboardsFragment()
            R.id.action_options -> OptionsFragment()
            else -> GameFragment()
        }
        Log.d("ChosenFragment", selectedFragment.toString())
        val transaction = supportFragmentManager.beginTransaction().replace(R.id.fragment_layout, selectedFragment)
        transaction.addToBackStack(null)
        transaction.commit()
        return true
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_truth_or_dare)
        bottomNav_truthordare.setOnNavigationItemSelectedListener(this)
        bottomNav_truthordare.selectedItemId = R.id.action_game
        initialFragmentLoad = true
        if (savedInstanceState != null) {
            return
        }
        val firstFragment = GameFragment()
        firstFragment.arguments = intent.extras
        supportFragmentManager.beginTransaction().replace(R.id.fragment_layout, firstFragment).commit();
    }

}

Я также хотел бы знать, почему я не могу изменить переменные, используя мои методы выше.

Теги:
kotlin
android-fragments

2 ответа

0

Вы можете попытаться остановить ваш фрагмент от раздувания его представления в onCreateView() следующим образом

 if (view != null) {
    ViewGroup parent = (ViewGroup) view.getParent();
    parent.removeView(view);
 } else {
    //here you put your current code from 'onCreateView()'
 }
  • 0
    view относится к getView() здесь? Я добавил свой onCreateView в свой код сейчас - я не уверен, как ваш код соответствует моей функции: i.imgur.com/C1EJKja.png
  • 0
    В вашем коде View view = inflater.inflate()... , затем return view ;
0

Вы можете использовать класс обработчика

public static class GameHandler {
  public static string truthisvisible;
}

а потом просто позвони

Gamehandler.truthisvisible = "stringafter";
val previousValue = Gamehandler.truthisvisible;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню