Сохранить данные из фрагмента в действии

Сохранение данных из фрагмента в действии не будет работать

Настройка: у меня есть 2 действия с 2 фрагментами, которые создаются динамически

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

Редактирование действия содержит редактирование фрагмента

Основная активность имеет базу данных

Фрагмент Main получает список из действия

Редактирование фрагмента изменяет список

Мой подход состоит в том, чтобы сохранить список в действии, когда основной фрагмент, содержащий список, уничтожен.

Текущее состояние Данные не записываются в базу данных при вызове ActivityForResult, а также в ландшафтном режиме.

Что меня смущает, так это то, что данные записываются при повороте дисплея, но я никогда не обновляю список в MainActivity.

 MainActivity 
================
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        getTable() // gets Data from DataBase

        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.frame_main, MainFragment.newInstance(dbList, true), "mainFragment")
                .commit()

        } else {
            // Destroys the Fragment because I want to load it with different config
            var  mainFragment = supportFragmentManager.findFragmentByTag("mainFragment") as MainFragment
            mainFragment.onDestroyView()
            // Checks if it is Landscape
            if (TabletHelper.isLandscape(this)) {
                supportFragmentManager.beginTransaction().replace(
                    R.id.frame_main,
                    MainFragment.newInstance(dbList, false),
                    "mainFragment"
                ).commit()
                supportFragmentManager.beginTransaction().replace(
                    R.id.frame_edit,
                    EditFragment.newInstance(null, null, true, null),
                    "editFragment"
                ).commit()
            } else {
                supportFragmentManager.beginTransaction().replace(
                    R.id.frame_main,
                    MainFragment.newInstance(dbList, true),
                    "mainFragment"
                ).commit()
            }
        }

    }

// interface implementation from the MainFragment
    override fun passList(list: ArrayList<Product>) {
        dbList.clear()
        dbList.addAll(list)
    }
// Write the list to the DataBase
    override fun onDestroy() {
        super.onDestroy()
        productsDBHelper.writeAllProducts(dbList, TABLE_NAME_MAIN)
    }


}

 MainFragment
==============
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if(savedInstanceState != null && savedState == null) {
            savedState = savedInstanceState.getBundle(BUNDLE)
        }
        if(savedState != null) {
            productList.addAll(savedState!!.getParcelableArrayList<Product>(PRODUCT_LIST_KEY)!!)
        }
        savedState = null

 //doing something with Layout...

        }
    }
// save bundel when onDestroyView is called 
   override fun onDestroyView() {
        super.onDestroyView()
        savedState = saveState()

    }
// Interface to pass the data to the Activity
    interface  OnFragmentMainClicked {
        fun passList(list: ArrayList<Product>)
    //..

    }


//creating Bundle for instance
    private fun saveState():Bundle{
        var state = Bundle()
        state.putParcelableArrayList(PRODUCT_LIST_KEY,productList)
        return state
    }
// Save Instance
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        if (savedState != null ){
            outState.putBundle(BUNDLE,savedState)
        }else{
            outState.putBundle(BUNDLE,saveState())
        }
    }









//My Thought was to save the Data always when when onDestroyView in the Fragment is called
     override fun onDestroyView() {
        super.onDestroyView()
        savedState = saveState()
        onFragmentMainClicked.passList(productList)
    }
//But it is not working. Result is that it clears whole list

person Simon    schedule 16.10.2019    source источник
comment
Используйте interface в качестве коммуникатора между действиями и фрагментами. Эта практика очень хороша для развития.   -  person Saadat Sayem    schedule 16.10.2019
comment
Я обновил код. Я использую интерфейс, но когда его использовать и почему список обновляется, когда я поворачиваю дисплей. Кстати, спасибо за ваш ответ   -  person Simon    schedule 17.10.2019


Ответы (1)


Я не знаю, почему вы ставите свой список в onDestroyView() в первую очередь. Шаги для связи, если вы хотите этот список, пока активность не активна. Итак, для этого создайте другой метод для получения вашего списка getList() внутри вашего интерфейса, который вернет ваш список. Поскольку вам нужно реализовать как passList(list: List<Type>), так и getList(): List<Type>. Теперь возьмите объект списка глобально в своей деятельности, заполните свой метод passList(list) и верните объект глобального списка (который уже заполнен). Затем просто вызовите getList() с объектом интерфейса. Я надеюсь, что вы получите свой список с помощью интерфейса. Надеюсь, поможет. Дай мне знать.

person Saadat Sayem    schedule 17.10.2019
comment
Эй, я исправил проблему, но я не понимаю, почему это работает так. Список в действии, который я передаю фрагменту как ParcelableArrayList, всегда обновляется, когда я делаю некоторые изменения во фрагменте. В действии теперь я всегда пишу в onPause список в свою базу данных, чтобы никакие изменения в списке действия не были потеряны. Так что в моем случае интерфейс не понадобился, но большое спасибо за ваши мысли. Может быть, вы можете объяснить мне, почему список, который я передаю во фрагмент с помощью аргументов, также перезаписывает список в действии. - person Simon; 17.10.2019