我有下面的布局
-MainActivity
-ParentFragment
-MaterialButtonToggleGroup
-ChildFragmentA
-RecyclerView
-ChildFragmentB
-RecyclerView
当我按下切换按钮时,我需要引用childFragment,这样我就可以显示/隐藏每个子片段.beginTransaction().show(childFragmentB!!).hide(childFragmentA!!)
,而不是替换它们
我很早就进入Android世界,我想知道在ViewModel中还是在ParentFragment中保留对孩子的引用更好?除了额外的代码之外,每个代码都有优点或缺点吗?
例如,在下面的Parent代码中,当初始化子代码时,我使用Parent中的属性,并最终为每个子代码指定tag
。当设备轮换发生时,我检查savedInstanceState
和tag
是否为空,以重新初始化它们。根据我的理解,我也可以使用onSaveInstanceState
(不包括)来实现相同的功能,但我也可以使用ViewModel中的属性,因为它不受旋转的影响。
视图模型:
class MyViewModel: ViewModel() {
private var mutableList = MutableLiveData<ArrayList<String>>()
val recyclerViewList: LiveData<ArrayList<String>> get() mutableList
fun addItemToMutableList(item: String) {
mutableList.value?.add(item)
}
// If I use these instead of the properties inside the parent I won't need the checks and the tags
var childFragmentA: ChildFragmentA? = null
var childFragmentB: ChildFragmentB? = null
}
家长:
class ParentFragment: Fragment() {
// _binding ...
// binding ...
private lateinit var myViewModel: MyViewModel
val childTagA = "childFragmentA"
val childTagB = "childFragmentB"
// Instead of using these would it be better to just use the properties inside the ViewModel
var childFragmentA: ChildFragmentA? = null
var childFragmentB: ChildFragmentB? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// _binding = initialize _binding ...
if (savedInstanceState == null) {
myViewModel = ViewModelProvider(requireActivity())[MyViewModel::class.java]
}
if (savedInstanceState == null && childFragmentManager.findFragmentByTag(childTagA) == null && childFragmentManager.findFragmentByTag(childTagB) == null)
childFragmentA = ChildFragmentA() // Alternatively I can use myViewModel.childFragmentA = ChildFragmentA()
childFragmentB = ChildFragmentB()
childFragmentManager.beginTransaction()
.add(binding.containerFrameLayout.id, childFragmentA!!, childTagA)
.add(binding.containerFrameLayout.id, childFragmentB!!, childTagB)
.hide(childFragmentB!!)
.commit()
} else {
childFragmentA = childFragmentManager.findFragmentByTag(childTagA) as ChildFragmentA
childFragmentB = childFragmentManager.findFragmentByTag(childTagB) as ChildFragmentB
}
return binding.root
}
}
1条答案
按热度按时间bvuwiixz1#
否,永远不要在
Viewmodel
中使用Fragment/Activity
的任何引用,主要有两个原因viewmodel
的生命周期与fragment
不同,这意味着它在fragment
上重复使用viewmodel
的同一个示例,因为配置更改而重新创建!在本例中,即使您在Viewmodel
中保存引用,这些引用也是死对象,可能会造成泄漏,因为即使保留了viewmodel
,前台的片段/活动示例也会与您在viewmodel
中保留的不同。1.单元测试和共享视图模型的使用,最好将android框架从viewmodel中隔离出来,以便在隔离的环境中更好地进行单元测试。