如何在recyclerview中加载数据? [英] How to load data in 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屋!