gpt4 book ai didi

android - 将对象发送到另一个 fragment 后进行更改

转载 作者:行者123 更新时间:2023-12-02 13:29:26 26 4
gpt4 key购买 nike

因此,我遇到了一个很奇怪的问题,我将一个对象从片段A 传递给片段B ,我在Fragment B中的新实例中修改了该对象,但是在更改了该对象的值之后,它也更改了该值当我弹出碎片B 并且该对象现在也针对进行修改片段A

片段A

...

override fun onItemClick(v: View?, position: Int) {
searchView.clearFocus()
val bundle = Bundle()
bundle.putSerializable("shop", landingAdapter.getItem(position))
findNavController().navigate(R.id.action_navigation_landing_to_shopFragment, bundle)
}

...

现在,从片段B我得到这个对象

片段B
    private lateinit var shop: Shop
private lateinit var shopAdapter:ShopAdapter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
shopAdapter = ShopAdapter(sharedViewModel, requireContext(),this)
arguments?.let {
shop = it.getSerializable(ARG_SHOP) as Shop
if (shop.products.isNotEmpty()) {
shopAdapter.setItems(shop.products)
}
}
}

现在,从片段A获取此Shop对象之后,仅在片段B中修改它
onViewCreated(){

shop.quantity = 1

}

但是当我返回到片段A时,现在Shop对象数量值是1,但是应该什么都不是,因为我只更改了片段B上的对象而不是片段A,并且在片段B中是该​​对象的新实例

我真的很困惑

编辑

到目前为止,我每次尝试从片段A到片段b发送一个新实例的尝试
   val bundle = Bundle()
bundle.putSerializable("shop", landingAdapter.getItem(position).copy())

findNavController().navigate(R.id.action_navigation_landing_to_shopFragment, bundle)



val bundle = Bundle()
val shop = landingAdapter.getItem(position)
bundle.putSerializable("shop", shop) findNavController().navigate(R.id.action_navigation_landing_to_shopFragment, bundle)


val bundle = Bundle()
val shop = Shop(landingAdapter.getItem(position).name,landingAdapter.getItem(position).quantity)
bundle.putSerializable("shop", shop)
findNavController().navigate(R.id.action_navigation_landing_to_shopFragment, bundle)

他们都没有将新的shop实例发送到片段B,因此,每当我更改片段B的数量时,片段A都会获得相同的数量值,该数量值不应突变

最佳答案

这实际上不是一个带有明显答案的明显问题。大约2个月前,我收到了这个问题,这也使我感到困惑,因为有时这是您的行为,有时不是。

首先要注意的是,当您为Fragment提供参数时,会将它们放在Bundle中。该 bundle 软件在内部存储字符串键的映射。

因此,当您调用fragment.setArguments(bundle)时,基本上就是在“发送 map ”。

因此,由于没有发生IPC(与“ Activity ”中通过Intent与Android对话的情况不同), map 中存在相同的对象实例。

在系统使用Bundle参数的属性之前,即为,并且确实重新创建了实例。

进程终止后(您将应用程序置于后台,Android回收了内存,并在重新启动时Android重建了任务堆栈,并根据从FragmentManager保存到onSaveInstanceState中的现有历史记录重新创建了 Activity 的Fragment),原始传递的参数用于“传入的属性。

这时,系统已重新创建了Serializable,如果您要导航回去,它将是与最初发送的实例不同的实例。

因此,您将获得相同的实例,因为Bundle在内部是 map 。

您还可以获得另一个实例,因为Android可以重新创建它。

解决方案:在发送实例之前,请使用副本以保持一致的行为。

编辑:

这也适用于可变列表内的嵌套对象。因此,如果您有类似

class A(
private val list: List<B>
)


class B(
private var blah: String
)

然后,如果通过 bundle 包发送了 BA发生了突变,则 List<B>中的 B会发生变化,这将在两个屏幕上均反射(reflect)出来,除非进程死亡。

所以这是要牢记的。

要创建副本,您可以执行
val copyList = a.list.map { it.copy() }

关于android - 将对象发送到另一个 fragment 后进行更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62363268/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com