Reputation: 45
When trying to get JSON data from an API and show it on the RecyclerView I'm getting following error:
I already use RecyclerView sometimes and I never had this problem.
MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activity_main)
overwriteOnPostInteractionListener()
setupObservers()
}
private fun setupObservers(){
mServiceRequest.searchPostsFromAPI().observe(this, Observer { posts ->
if (posts != null){
loadRecyclerView()
mPostList = posts.toMutableList()
}
})
}
private fun loadRecyclerView() {
recyclerView.adapter = PostListAdapter(mPostList, mOnPostListInteractionListener)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
}
Adapter:
class PostListAdapter(private val postList: List<PostModel>,
private val onPostListInteractionListener: OnPostListInteractionListener):
RecyclerView.Adapter<PostViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
val inflate = LayoutInflater.from(parent.context)
val view = inflate.inflate(R.layout.posts , parent, false)
return PostViewHolder(view, parent.context, onPostListInteractionListener)
}
override fun getItemCount(): Int {
return postList.count()
}
override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
holder.bindTask(postList[position])
}}
ViewHolder:
class PostViewHolder(itemView: View, private val context: Context,
private val onPostListInteractionListener: OnPostListInteractionListener)
: RecyclerView.ViewHolder(itemView) {
private val postTitle = itemView.findViewById<TextView>(R.id.titleTextViewMain)
private val postBody = itemView.findViewById<EditText>(R.id.bodyEditText)
fun bindTask(post: PostModel){
postTitle.text = post.title
postBody.setText(post.body)
postTitle.setOnClickListener {
onPostListInteractionListener.onListClick(post.id)
}
}}
I searched a lot how to solve this error but I can't.
Upvotes: 1
Views: 515
Reputation: 40898
You build your RecyclerView adapter before feeding the data to the list, so you need to call mPostList = posts.toMutableList()
before instantiating your adapter.
So, change setupObservers()
with:
private fun setupObservers(){
mServiceRequest.searchPostsFromAPI().observe(this, Observer { posts ->
if (posts != null){
mPostList = posts.toMutableList()
loadRecyclerView()
}
})
}
Also set your adapter after, you completely build the RecyckerView
. So change the order of loadRecyclerView() as below.
private fun loadRecyclerView() {
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
recyclerView.adapter = PostListAdapter(mPostList, mOnPostListInteractionListener)
}
Setting RecyclerView
adapter before layout can cause issues.
Side note:
You instantiate your adapter every time your list is changed, and that's not the right way, and it's better to create your stuff (including the adapter) only once in a lifecycle, and then make setters each time you want to change them instead of instantiating them over and over again.
So, you can instantiate your adapter only once in onCreate()
method and create a method in your adapter that takes the posts setPosts(private val postList: List<PostModel>)
and set them internally .. whenever you need to change adapter list, just call setPosts
Upvotes: 2