如何使用 ViewModel(MVVM) 将对象从片段传递到 activity 详细视图?
How to pass an object from a fragment to an activity detail view using ViewModel(MVVM)?
我正在使用 MVVM 作为架构,如何将对象从片段(回收器 + viewModel)传递到 activity(详细视图 + viewModel)?
这是片段的视图模型
class BuyViewModel : ViewModel() {
private lateinit var buys: MutableLiveData<List<Buy>>
private var buyRemote = BuyRemote()
private var buyRepository: BuyRepository = BuyRepository.getInstance(buyRemote)
fun getBuys(): LiveData<List<Buy>> {
if(!::buys.isInitialized) {
buys = MutableLiveData()
buys = buyRepository.getBuys()
}
return buys
}
}
这是片段的适配器
class BuyAdapter(internal var context: Context,
private var resource: Int,
private var buyList: ArrayList<Buy>
) : RecyclerView.Adapter<BuyAdapter.ViewHolder>() {
override fun getItemCount(): Int {
return buyList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context)
.inflate(resource, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val buy: Buy = buyList[position]
val propertyImages: List<String> =
buy.propertyImage.split(",")
//Start DetailView Activity
holder.itemView.setOnClickListener {
Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show()
val intent = Intent(context, BuyDetailActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
}
}
+++++++++++++++code removed for brevity+++++++++++++++++
最后是片段
class BuyFragment : Fragment() {
companion object {
fun newInstance() = BuyFragment()
}
private lateinit var viewModel: BuyViewModel
private val buyList = ArrayList<Buy>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(BuyViewModel::class.java)
viewModel.getBuys().observe(this, Observer<List<Buy>> { buys ->
buyList.addAll(buys)
(rvBuy.adapter as BuyAdapter).notifyDataSetChanged()
})
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.buy_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
rvBuy.layoutManager = LinearLayoutManager(context)
rvBuy.adapter = BuyAdapter(activity!!.applicationContext,
R.layout.buy_card, buyList)
}
如何在尊重最佳实践的同时实现这一点。
当用户从回收器视图(片段)中单击一个项目时,它会将对象 "Buy" 传递给 activity。
activity 是否应该单独使用视图模型?如何?
activity 是否应该使用与片段回收器视图相同的视图模型?
您可以使用绑定到片段之间 activity 的共享视图模型。
像这样获取片段中的 ViewModel。
val sharedViewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)
然后在列表片段onClick
classsharedViewModel.onItemClicked(item)
SharedViewModel {
private val _selectedItem = MutableLiveData<T>()
val selectedItem: LiveData<T> get() = _selectedItem
fun onItemClick(item: T) {
_selectedItem.value = item
}
}
然后在细节片段
sharedViewModel.selectedItem.observe {
detailViewModel.setItem(it)
}
然后在详细视图模型中加载项目并显示。
更新
要从 activity 获取视图模型访问共享视图模型:
val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
然后像在片段中一样观察 selectedItem
LiveData。
我正在使用 MVVM 作为架构,如何将对象从片段(回收器 + viewModel)传递到 activity(详细视图 + viewModel)?
这是片段的视图模型
class BuyViewModel : ViewModel() {
private lateinit var buys: MutableLiveData<List<Buy>>
private var buyRemote = BuyRemote()
private var buyRepository: BuyRepository = BuyRepository.getInstance(buyRemote)
fun getBuys(): LiveData<List<Buy>> {
if(!::buys.isInitialized) {
buys = MutableLiveData()
buys = buyRepository.getBuys()
}
return buys
}
}
这是片段的适配器
class BuyAdapter(internal var context: Context,
private var resource: Int,
private var buyList: ArrayList<Buy>
) : RecyclerView.Adapter<BuyAdapter.ViewHolder>() {
override fun getItemCount(): Int {
return buyList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context)
.inflate(resource, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val buy: Buy = buyList[position]
val propertyImages: List<String> =
buy.propertyImage.split(",")
//Start DetailView Activity
holder.itemView.setOnClickListener {
Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show()
val intent = Intent(context, BuyDetailActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
}
}
+++++++++++++++code removed for brevity+++++++++++++++++
最后是片段
class BuyFragment : Fragment() {
companion object {
fun newInstance() = BuyFragment()
}
private lateinit var viewModel: BuyViewModel
private val buyList = ArrayList<Buy>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(BuyViewModel::class.java)
viewModel.getBuys().observe(this, Observer<List<Buy>> { buys ->
buyList.addAll(buys)
(rvBuy.adapter as BuyAdapter).notifyDataSetChanged()
})
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.buy_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
rvBuy.layoutManager = LinearLayoutManager(context)
rvBuy.adapter = BuyAdapter(activity!!.applicationContext,
R.layout.buy_card, buyList)
}
如何在尊重最佳实践的同时实现这一点。 当用户从回收器视图(片段)中单击一个项目时,它会将对象 "Buy" 传递给 activity。 activity 是否应该单独使用视图模型?如何? activity 是否应该使用与片段回收器视图相同的视图模型?
您可以使用绑定到片段之间 activity 的共享视图模型。 像这样获取片段中的 ViewModel。
val sharedViewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)
然后在列表片段onClick
classsharedViewModel.onItemClicked(item)
SharedViewModel {
private val _selectedItem = MutableLiveData<T>()
val selectedItem: LiveData<T> get() = _selectedItem
fun onItemClick(item: T) {
_selectedItem.value = item
}
}
然后在细节片段
sharedViewModel.selectedItem.observe {
detailViewModel.setItem(it)
}
然后在详细视图模型中加载项目并显示。
更新
要从 activity 获取视图模型访问共享视图模型:
val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
然后像在片段中一样观察 selectedItem
LiveData。