如何在recyclerview中加载数据? [英] How to load data in recyclerview?

查看:170
本文介绍了如何在recyclerview中加载数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 Android 应用程序并尝试在 Recyclerview 中设置数据,我正在使用带有 kotlin 的 MVVM 架构模式,我可以在 logcat 中看到数据,但是当应用程序加载时,我在我的 recyclerview 中没有看到任何数据.以下是我的代码.

I am creating one Android app and trying to set the data in Recyclerview, I am using MVVM architecture pattern with kotlin, I can see data in logcat but when app loads I am not seeing any data in my recyclerview. Following is my code.

主活动

class MainActivity : AppCompatActivity() {
    lateinit var productViewModel: ProductViewModel
    private lateinit var binding: ActivityMainBinding

    val adapter = ProductAdapter()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        val productService = RetrofitHelper.getInstance().create(ProductService::class.java)

        val productRepository = ProductRepository(productService)
        productViewModel = ViewModelProvider(this, ProductViewModelFactory(productRepository)).get(ProductViewModel::class.java)

        binding.recyclerview.adapter = adapter
        productViewModel.products.observe(this,{
            Log.d("TEST",it.toString())
            adapter.notifyDataSetChanged()

        })
    }
}

产品适配器

class ProductAdapter : RecyclerView.Adapter<ProductViewHolder>() {
    var movies = mutableListOf<MobileList>()
    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
        val inflater = LayoutInflater.from(parent.context)

        val binding = AdapterLayoutBinding.inflate(inflater, parent, false)
        return ProductViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
        val movie = movies[position]
        holder.binding.name.text = movie.products.get(position).name
        Glide.with(holder.itemView.context).load(movie.products.get(position).image_url).into(holder.binding.imageview)

    }

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

}

class ProductViewHolder(val binding: AdapterLayoutBinding) : RecyclerView.ViewHolder(binding.root) {

}

仓库类

class ProductRepository (private val productService: ProductService) {

    private val productLiveData = MutableLiveData<MobileList>()
    val products:LiveData<MobileList>
    get() = productLiveData

    suspend fun getProducts(){
        val products = productService.getQuotes()
        if(products?.body()!=null)
        {
            productLiveData.postValue(products.body())
        }
    }
}

视图模型

class ProductViewModel (private val productRepository: ProductRepository ) :ViewModel() {
    init {
        viewModelScope.launch(Dispatchers.IO){
            productRepository.getProducts()
        }
    }

    val products : LiveData<MobileList>
    get() = productRepository.products
}

工厂

class ProductViewModelFactory (private val productRepository: ProductRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return ProductViewModel (productRepository) as T
    }

}

型号

data class MobileList(
    val products: List<Product>
)

data class Product(
    val image_url: String,
    val name: String,
    val price: String,
    val rating: Int
)

JSON 响应

{
  "products": [
    {
      "name": "test",
      "price": "34999",
      "image_url": "url",
      "rating": 4
    },
    {
      "name": "test2",
      "price": "999",
      "image_url": "url",
      "rating": 4
    },]}

推荐答案

首先确保您在 RecyclerView 上设置了 layoutManager.

First of all make sure you have layoutManager set on the RecyclerView.

这里的问题是你的 ProductAdapter 从来没有数据.notifyDataSetChanged 不是通知适配器您修改/添加/更新数据集的魔术棒,然后您将调用 notifyDataSetChanged .这就是它的工作原理.

The problem here is Your ProductAdapter never had the data . notifyDataSetChanged is not a magic stick to notify the adapter you modify/add/update the dataset and then You will call notifyDataSetChanged . that's how it works .

在您的情况下,您有 movies 列出您的适配器,但您从未为其分配任何内容,它始终为空.有几种方法.只是为了让它工作你可以有一个方法在你的适配器中添加数据,然后通知它.

In your case You have movies list your adapter but you never assigned anything to it its always empty . There are several ways to it. Just to make it work You can have a method to add the data in your adapter and then notify it.

fun addData(data:List<MobileList>){
        movies.addAll(data)
        notifyDataSetChanged()
    }

现在,当您在更改中获取数据时,您将调用此方法.

Now when you get the data inside on change you call this method .

productViewModel.products.observe(this,{
       it?.let{ items ->
        adapter.addData(items)
       }
    })

这应该可行.

更新类型修复 - 好像你的类型搞砸了.为什么你的 repo 返回一个 MobileList 的对象?当您在适配器中使用 MobileList 列表时.您的适配器应该包含 var movies = mutableListOf().

Update on type fix - Seems like your type is messed up . Why is your repo returns a object of MobileList? While you are using a list of MobileList in adapter . Your adapter should hold var movies = mutableListOf<Products>().

productViewModel.products.observe(this,{
       it?.let{ item ->
        adapter.addData(item.products)
       }
    })

这篇关于如何在recyclerview中加载数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆