从 Recycler Adapter 访问 ViewModel 的正确方法
Proper way to access ViewModel from Recyler Adaper
我有一个保存数据和获取数据的数据存储库,它作为构造函数传递到 ViewModel。我在 ViewModel 中有一些方法可以获取和保存数据。
我为每一行(RecyclerView 列表中的项目)单击了一个按钮,它使用 ViewModel 保存数据。
我发现我可以直接调用 ViewModel 将其初始化到构造函数中,我检查了 Google Android 示例,这部分未涵盖。
如下所示:
复制自:Databinding Recyclerview and onClick
private ExampleViewModel exampleViewModel;
public ExampleListAdapter(Context context, List<Model> models) {
this.context = context;
this.models = models;
// ...
exampleViewModel = ViewModelProviders.of((FragmentActivity) context).get(ExampleViewModel.class);
}
但是,我也可以通过从 Activity 传递一个 ViewModel 对象和上下文来调用 ViewModel。
那么调用 ViewModel 的正确方法是什么?
这是你的 pojo class
data class Item(val id: Int)
这是你的适配器。
class Adapter : RecyclerView.Adapter<Adapter.ViewHolder>() {
var items: List<Item> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
var callback: Callback? = null
override fun getItemCount(): Int {
return items.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.simple_textview, parent, false)
return ViewHolder(itemView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
holder.itemView.setOnClickListener {
callback?.onItemClicked(item)
}
holder.bindItem(item)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItem(item: Item) {
// Fill layout
}
}
interface Callback {
fun onItemClicked(item: Item)
}
}
这是您的视图模型 class。
class MyViewModel : ViewModel(), Adapter.Callback {
override fun onItemClicked(item: Item) {
}
}
这是你的片段。
class MyFragment : Fragment() {
private val adapter = Adapter()
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
adapter.callback = myViewModel
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.my_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
adapter.items = listOf(
Item(1),
Item(2)
)
//Setup recyclerView etc.
}
}
我有一个保存数据和获取数据的数据存储库,它作为构造函数传递到 ViewModel。我在 ViewModel 中有一些方法可以获取和保存数据。
我为每一行(RecyclerView 列表中的项目)单击了一个按钮,它使用 ViewModel 保存数据。
我发现我可以直接调用 ViewModel 将其初始化到构造函数中,我检查了 Google Android 示例,这部分未涵盖。
如下所示: 复制自:Databinding Recyclerview and onClick
private ExampleViewModel exampleViewModel;
public ExampleListAdapter(Context context, List<Model> models) {
this.context = context;
this.models = models;
// ...
exampleViewModel = ViewModelProviders.of((FragmentActivity) context).get(ExampleViewModel.class);
}
但是,我也可以通过从 Activity 传递一个 ViewModel 对象和上下文来调用 ViewModel。
那么调用 ViewModel 的正确方法是什么?
这是你的 pojo class
data class Item(val id: Int)
这是你的适配器。
class Adapter : RecyclerView.Adapter<Adapter.ViewHolder>() {
var items: List<Item> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
var callback: Callback? = null
override fun getItemCount(): Int {
return items.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.simple_textview, parent, false)
return ViewHolder(itemView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
holder.itemView.setOnClickListener {
callback?.onItemClicked(item)
}
holder.bindItem(item)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItem(item: Item) {
// Fill layout
}
}
interface Callback {
fun onItemClicked(item: Item)
}
}
这是您的视图模型 class。
class MyViewModel : ViewModel(), Adapter.Callback {
override fun onItemClicked(item: Item) {
}
}
这是你的片段。
class MyFragment : Fragment() {
private val adapter = Adapter()
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
adapter.callback = myViewModel
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.my_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
adapter.items = listOf(
Item(1),
Item(2)
)
//Setup recyclerView etc.
}
}