I have succeeded pulling JSON from Reddit API but I cannot put it into my RecyclerView. I set a Log to check if my JSON is empty or null, and the Log successfully print the desired output, so that means my JSON is not empty and contains the necessary data.
Here is my HomeFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(javaClass.simpleName, "onViewCreated")
val rv = binding.recyclerView
val adapter = PostRowAdapter(viewModel)
rv.adapter = adapter
rv.layoutManager = LinearLayoutManager(binding.root.context)
viewModel.netFetchData()
viewModel.observeData().observe(viewLifecycleOwner) {
Log.d("asd","show me the author from json first index : " it.get(0).author)
adapter.submitList(it)
adapter.notifyDataSetChanged()
}
//adapter.notifyDataSetChanged()
}
Here is my MainViewModel.kt
fun netFetchData() = viewModelScope.launch(
context = viewModelScope.coroutineContext
Dispatchers.IO) {
data.postValue(repository.getPosts(subreddit.value.toString()))
}
fun observeData(): LiveData<List<RedditPost>> {
return data
}
Here is my PostRowAdapter.kt
class PostRowAdapter(private val viewModel: MainViewModel)
: ListAdapter<RedditPost, PostRowAdapter.VH>(RedditDiff()) {
private var awwRow = listOf<RedditPost>()
class RedditDiff : DiffUtil.ItemCallback<RedditPost>() {
override fun areItemsTheSame(oldItem: RedditPost, newItem: RedditPost): Boolean {
return oldItem.key == newItem.key
}
override fun areContentsTheSame(oldItem: RedditPost, newItem: RedditPost): Boolean {
return RedditPost.spannableStringsEqual(oldItem.title, newItem.title) &&
RedditPost.spannableStringsEqual(oldItem.selfText, newItem.selfText) &&
RedditPost.spannableStringsEqual(oldItem.publicDescription, newItem.publicDescription) &&
RedditPost.spannableStringsEqual(oldItem.displayName, newItem.displayName)
}
}
inner class VH(val binding: RowPostBinding)
: RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val binding = RowPostBinding.inflate(LayoutInflater.from(parent.context),
parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int) {
val binding = holder.binding
awwRow[position].let{
binding.title.text = it.title
Glide.glideFetch(it.imageURL,it.thumbnailURL,binding.image)
binding.selfText.text = it.selfText
binding.score.text = it.score.toString()
binding.comments.text = it.commentCount.toString()
}
}
override fun getItemCount() = awwRow.size
}
I thought my code was correct, but when I ran the app, the RecyclerView still blank. Where am I wrong?
CodePudding user response:
your PostRowAdapter
is populating awwRow
list, which is empty on start and never updated, thus this RecyclerView
will always contain 0 elements
if you are using ListAdapter
and submitList(...)
method then you shouldn't override getItemCount
and you shouldn't have own data list, so remove these lines
private var awwRow = listOf<RedditPost>() // on top
override fun getItemCount() = awwRow.size // on bottom
if you want access to whole list set with submitList()
method then you can call inside adapter getCurrentList()
. if you need a particular item at position (like in onBindViewHolder
) then use getItem(position)
. So instead of
awwRow[position].let{
you should have
getItem(position).let{