如何使用ViewModel(MVVM)将对象从片段传递到活动详细信息视图?

时间:2019-02-28 22:07:37

标签: android android-intent kotlin android-viewmodel android-mvvm

我正在使用MVVM作为体系结构,如何将对象从片段(回收器+ viewModel)传递到活动(详细视图+ 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)
}

在尊重最佳实践的同时,如何实现这一目标。 当用户单击回收者视图(片段)中的项目时,它将把“购买”对象传递给活动。 该活动是否应该单独使用视图模型?怎么样? 活动是否应该使用与片段回收器视图相同的视图模型?

1 个答案:

答案 0 :(得分:0)

您可以使用与片段之间的活动相关联的共享视图模型。 像这样获取片段中的ViewModel。

val sharedViewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)

然后在列表片段onClicksharedViewModel.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)
}

然后在详细视图模型中加载项目并显示。

更新

要从活动中访问共享视图模型,请获取视图模型:

val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)

然后像片段一样观察selectedItem LiveData。