【发布时间】:2021-04-02 18:47:55
【问题描述】:
我有两个共享相同视图模型的片段
ShoeListFragment 显示带有 fab 的 sheos 列表,ShoeDetailsFragment 让用户在 fab 点击时添加新鞋
在ShoeDetailsFragment 用户可以点击添加或取消。添加后,鞋子将被添加并显示在ShoeListFragment
如果用户点击取消,我们会将用户导航至ShoeListFragment。
现在在第一次运行中,我尝试在 fab 中添加新鞋,点击它被添加并显示。
在第二次运行中,我尝试了取消按钮,然后导航到 ShoeListFragment。
但是,如果在同一次运行中我尝试添加,然后导航到 ShoeListFragment,我点击 fab,它被点击,ShoeDetailsFragment 被调用,但布局不可见!
我的意思是 ShoeListFragment 布局仅可见。
ShoeListFragment
class ShoeListFragment : Fragment() {
lateinit var viewModel : ShoeListViewModel
lateinit var binding : FragmentShoeListBinding
lateinit var parentLayout: LinearLayout
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater , R.layout.fragment_shoe_list , container , false)
binding.fabAddShoe.setOnClickListener({
Timber.i("fab clicked")
findNavController().navigate(ShoeListFragmentDirections.actionShoesFragmentToShoeDetailFragment())
})
viewModel = ViewModelProvider(requireActivity()).get(ShoeListViewModel::class.java)
Timber.i(viewModel.mShoeList.size.toString())
viewModel.shoeList.observe(viewLifecycleOwner , Observer { shoeList ->
Timber.i("List shoe observer")
displayList(shoeList)
})
parentLayout = binding.llParent
setHasOptionsMenu(true)
// Inflate the layout for this fragment
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
Timber.i("onCreateOptionsMenu")
inflater.inflate(R.menu.main_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
}
// Menu item id must match the destination id to navigate there
override fun onOptionsItemSelected(item: MenuItem): Boolean {
Timber.i("onOptionsItemSelected")
return NavigationUI.onNavDestinationSelected(item, requireView().findNavController())
|| super.onOptionsItemSelected(item)
}
}
ShoeDetailFragment
class ShoeDetailFragment : Fragment() {
lateinit var binding : FragmentShoeDetailBinding
lateinit var viewModel : ShoeListViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// View binding
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_shoe_detail , container , false)
// Data binding - shared view model
viewModel = ViewModelProvider(requireActivity()).get(ShoeListViewModel::class.java)
binding.shoeListViewModel = viewModel
binding.shoeModel = Shoe("" , 0.0 , "" , "")
//Observers
viewModel.isCancelAdd.observe(viewLifecycleOwner , Observer { isCancel ->
Timber.i("Fragment Cancel shoe")
findNavController().navigate(ShoeDetailFragmentDirections.actionShoeDetailFragmentToShoesFragment())
})
viewModel.isAddShoe.observe(viewLifecycleOwner , Observer { isAdd ->
findNavController().navigate(ShoeDetailFragmentDirections.actionShoeDetailFragmentToShoesFragment())
})
// Inflate the layout for this fragment
return binding.root
}
共享视图模型
class ShoeListViewModel : ViewModel() {
/* Should we make shoeList observing mShoeList instead of doing
shoeList.value = mShoeList in once we add new shoe?
*/
private var _shoeList = MutableLiveData<MutableList<Shoe>>()
val shoeList : LiveData<MutableList<Shoe>>
get() = _shoeList
private var _isCancelAdd = MutableLiveData<Boolean>()
val isCancelAdd : LiveData<Boolean>
get() = _isCancelAdd
private var _isAddShoe = MutableLiveData<Boolean> ()
val isAddShoe : LiveData<Boolean>
get() = _isAddShoe
var mShoeList : MutableList<Shoe>
init {
mShoeList = mutableListOf(
Shoe("Filla" , 40.0 , "Filla" , "Filla shoes") ,
Shoe("Addidad" , 30.0 , "Addidas" , "Addidas shoes")
)
_shoeList.value = mShoeList
}
fun addShoe (shoe : Shoe) {
_isAddShoe.value = true
mShoeList.add(shoe)
_shoeList.value = mShoeList
Timber.i("In Add shoe")
}
fun cancelAddShoe () {
_isCancelAdd.value = true
Timber.i("In Cancel shoe")
}
我试过调试它,第二次这条线在shoeDetailsFragment中执行
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_shoe_detail , container , false)
直到到达
return binding.root
然后这被调用了
binding = DataBindingUtil.inflate(inflater , R.layout.fragment_shoe_list , container , false)
这就是为什么我认为鞋子细节片段不可见的原因。 但是为什么会发生这种行为呢?
【问题讨论】:
标签: android kotlin mvvm navigation viewmodel