【问题标题】:How to instantiate viewmodel in recycler view adapter class如何在回收器视图适配器类中实例化视图模型
【发布时间】:2021-07-20 09:13:11
【问题描述】:

我正在尝试创建类似于布局的 Play 商店,在该布局中,我使用视图模型在回收器视图适配器类中获取数据,但在适配器类中的视图模型实例化时出现错误。

这是 JSON 响应:

{
"status": "200",
"message": "Success",
"result": [
    {
        "_id": "60f516fa846e059e2f19c50c",
        "category": "Shirts",
        "sku": [
            {
                "name": "Oxford shirt",
                "brand": "John players",
                "price": "25",
                "color": "Blue",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/shi1.jpg?alt=media&token=64779194-e3b5-484f-a610-c9a20648b64c"
            },
            {
                "name": "Buttoned down",
                "brand": "Gap originals",
                "price": "45",
                "color": "Pink",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/shi2.jpg?alt=media&token=0b207b90-f1bc-4771-b877-809648e6bdc1"
            },
            {
                "name": "Collared",
                "brand": "Arrow",
                "price": "30",
                "color": "White",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/shi3.jpg?alt=media&token=2c1bb3f8-e739-4f09-acbc-aa11fed795e3"
            },
            {
                "name": "Printed",
                "brand": "John players",
                "price": "30",
                "color": "Olive green",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/shi4.jpg?alt=media&token=666f94bf-4769-44fe-a909-3c81ca9262f7"
            },
            {
                "name": "Hoodie",
                "brand": "Levis",
                "price": "44",
                "color": "Yellow",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/shi5.jpg?alt=media&token=65fccef4-a882-4278-b5df-f00eb2785bf1"
            }
        ]
    },
    {
        "_id": "60f51c37846e059e2f19c50f",
        "category": "Shoes",
        "sku": [
            {
                "name": "Sneakers",
                "brand": "Puma",
                "price": "35",
                "color": "Black and white",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/sho1.jpg?alt=media&token=d078988d-9e85-4313-bb4a-c9d46e09f0b9"
            },
            {
                "name": "Running shoe",
                "brand": "Nike",
                "price": "99",
                "color": "Multicolor",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/sho2.jpg?alt=media&token=ed2e7387-3cf6-44df-9f7d-69843eb0bcdf"
            },
            {
                "name": "Yezzy",
                "brand": "Adidas",
                "price": "349",
                "color": "Gray",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/sho3.jpg?alt=media&token=2c37ef76-37bb-4bdd-b36c-dea32857291f"
            },
            {
                "name": "Sneakers",
                "brand": "Puma",
                "price": "79",
                "color": "Black",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/sho4.jpg?alt=media&token=4acd763e-8b93-47cd-ba45-92f34af4cf83"
            },
            {
                "name": "Joyride running",
                "brand": "Nike",
                "price": "80",
                "color": "White",
                "img": "https://firebasestorage.googleapis.com/v0/b/koovs-1ff31.appspot.com/o/sho5.jpg?alt=media&token=e3780dcc-52cb-49d5-9791-e0a44870716c"
            }
        ]
      }
   ]
}

下面是我的代码:

这是包含类别标题和水平回收器视图的父回收器视图行。

parent_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/catTitle"
    android:textStyle="bold"
    android:textSize="18sp"
    android:textColor="#345"/>

<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/childRecycler"
    android:layout_below="@+id/catTitle"
    android:layout_marginTop="8dp"/>

</RelativeLayout>

这是包含与类别标题相关的图像的水平回收器视图行。

child_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.cardview.widget.CardView
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:cardCornerRadius="3dp"
    app:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/img"/>

    </LinearLayout>

</androidx.cardview.widget.CardView>

</RelativeLayout>

CatImgAdapter.kt

class CatImgAdapter(private val context: Context,private val imgList:List<Sku>): RecyclerView.Adapter<CatImgAdapter.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

    return ViewHolder(ChildRowBinding.inflate(LayoutInflater.from(parent.context),parent,false))
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    val model = imgList[position]
    Glide.with(context).load(model.img).into(holder.binding.img)
}

override fun getItemCount(): Int {
    return imgList.size
}

data class ViewHolder(val binding:ChildRowBinding): RecyclerView.ViewHolder(binding.root)

}

CategoryAdapter.kt

class CategoryAdapter(private val context: Context,private val categories:List<Result>): 
RecyclerView.Adapter<CategoryAdapter.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
   return ViewHolder(ParentRowBinding.inflate(LayoutInflater.from(parent.context),parent,false))
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    val model = categories[position]
    holder.binding.catTitle.text = model.category

    val viewModel = ViewModelProvider(context).get(CatImagesViewModel::class.java)
}

override fun getItemCount(): Int {
    return categories.size
}

class ViewHolder(val binding:ParentRowBinding): RecyclerView.ViewHolder(binding.root)
}    

val viewModel = ViewModelProvider(context).get(CatImagesViewModel::class.java) 这一行出现错误。

CatImageViewModel.kt

class CatImagesViewModel: ViewModel() {

private var catImageList:MutableLiveData<List<Sku>> = MutableLiveData()

fun getCatImg(): LiveData<List<Sku>>{

    viewModelScope.launch(Dispatchers.IO) {

        val retrofit = RetrofitClient.getRetrofitClient().create(ApiService::class.java)
        val response = retrofit.getCatImg()

        if(response.isSuccessful){

            val cnt = response.body()!!.result.size

            for(i in 0 until cnt){
                catImageList.postValue(response.body()!!.result[i].sku)
            }
        }
    }

    return catImageList
  }
}

有人告诉我如何在适配器类中实例化上述视图模型。

【问题讨论】:

    标签: android kotlin mvvm viewmodel


    【解决方案1】:

    我不知道你想在这里做什么,但无论如何你都不应该在 RecyclerView 适配器中实例化 ViewModel。

    ViewModel 应该存在于托管您正在使用的回收器视图的 Fragment 或 Activity 中,因为它与特定 Activity 或 Fragment 的生命周期相关联。

    所以在那里进行实例化并在那里点击 API 并将数据传递给 RecyclerView,因为这就是它所需要的。数据。它不应该与 ViewModel 或 API 调用有任何关系。

    【讨论】:

    • 我正在尝试创建嵌套回收器视图,如 Play 商店,因此我将 Title 和水平 RecyclerView 作为父回收器视图的行项。所以在父回收器视图的适配器中,我试图实例化视图模型以获取水平回收器视图的数据。
    • 我明白了,但这仍然是错误的。那么结构应该是您应该向您的父 recyclerView 提交不同数据的列表,然后从那里分配给水平数据。
    • 我已经更新了我的帖子请让我现在如何纠正它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2017-04-28
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多