android - 如何使用 ViewModel(MVVM) 将对象从 fragment 传递到 Activity 详细信息 View ?

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

我正在使用 MVVM 作为架构,如何将对象从 fragment (回收器 + viewModel)传递到 Activity (详细 View + viewModel)?

这是 fragment 的 View 模型

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
}

}

这是 fragment 的适配器

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)
    }
}

++++++++++++++++为简洁起见删除了代码++++++++++++++++++

最后是 fragment

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)
}

我如何在遵守最佳实践的同时实现这一目标。 当用户从回收器 View ( fragment )中单击一个项目时,它会将一个对象“购买”传递给一个 Activity 。 该 Activity 是否应该单独使用 View 模型?如何? Activity 是否应该使用与 fragment 回收器 View 相同的 View 模型?

最佳答案

您可以使用与 fragment 之间的 Activity 相关联的共享 View 模型。 像这样获取 fragment 中的 ViewModel。

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

然后在列表 fragment onClicksharedViewModel.onItemClicked(item)

SharedViewModel {
    private val _selectedItem = MutableLiveData<T>()
    val selectedItem: LiveData<T> get() = _selectedItem

    fun onItemClick(item: T) {
        _selectedItem.value = item
    }
}

然后在细节 fragment 中

sharedViewModel.selectedItem.observe {
    detailViewModel.setItem(it)
}

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

更新

要从 Activity 中访问共享 View 模型,请获取 View 模型:

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

然后像在 fragment 中一样观察 selectedItem LiveData。

关于android - 如何使用 ViewModel(MVVM) 将对象从 fragment 传递到 Activity 详细信息 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54935028/

相关文章:

android - 如何从不同的 Activity 获取主启动 Activity 的 Intent?

java - 如何在 Android 中以编程方式调用电话?

android - 无法从CoroutineScope启动访问暂停Dao功能

java - 如何在 OkHttp 拦截器中获取方法的返回类型?

testing - kotlin 多平台覆盖?

java - 项目 'PrjName' 缺少所需的库 : 'libs/android-viewbadger.jar' PrjName

android - 将 View 添加到选项卡与将 Activity 添加到选项卡 android

Android广播接收器没有收到 Intent

android - 创建 Android 背景图片

android - Android 设备旋转时如何保留警报对话框