从 Activity 的 Fragment 中保存数据
Posted
技术标签:
【中文标题】从 Activity 的 Fragment 中保存数据【英文标题】:Save Data from Fragment in Activity 【发布时间】:2019-10-16 19:59:27 【问题描述】:将 Fragment 中的数据保存在 Activity 中不起作用
设置:我有 2 个 Activity 和 2 个动态创建的片段
在横向模式下,Activity Main 包含两个 Fragment, 否则只有 Fragment Main 并通过 ActivityForResult 启动 Activity 编辑
活动编辑包含片段编辑
Activity Main 有一个数据库
Fragment Main 从 Activity 中获取一个 List
片段编辑修改列表
我的方法是在包含列表的 Fragment Main 被销毁时将列表保存在 Activity 中。
当前状态 调用 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
【问题讨论】:
使用interface
作为Activity和Fragment之间的通信器。这种做法非常适合开发。
我更新了代码。我正在使用一个界面,但是何时使用它以及为什么当我转动显示器时列表会更新。顺便说一句谢谢你的回应
【参考方案1】:
我不知道您为什么首先将列表设置为onDestroyView()
。如果您想要此列表,则在活动生效之前进行通信的步骤。因此,要实现这一点,请创建另一种方法来在您的界面中获取您的列表getList()
,这将返回您的列表。因为你必须同时实现passList(list: List<Type>)
和getList(): List<Type>
。现在,在您的活动中全局获取一个列表对象,填充到您的 passList(list)
方法中并返回全局列表对象(已填充)。
然后只需使用接口对象调用getList()
。我希望你能通过界面得到你的清单。
希望能帮助到你。告诉我。
【讨论】:
嘿,我解决了这个问题,但我不明白为什么它会这样。我作为 ParcelableArrayList 传递给 Fragment 的 Activity 列表总是在我对 Fragment 进行一些修改时更新。现在在 Activity 中,我总是将 onPause 列表写入我的数据库,这样 Activity 列表中的任何更改都不会丢失。因此,在我的情况下不需要该界面,但非常感谢您的想法。也许你可以解释一下为什么我通过参数传递给片段的列表也会覆盖活动中的列表。以上是关于从 Activity 的 Fragment 中保存数据的主要内容,如果未能解决你的问题,请参考以下文章