On recyclerview I'm setting a list, using MVVM where I'm getting an error, IndexOutOfBoundsException. code I use for recyclerview adapter is below - onBindViewHolder is where I set articles:List
class MainAdapter(private val context: Context,private val articles:List<Article>) : ListAdapter<Article, MainAdapter.MainViewHolder>(DiffUtil()) {
inner class MainViewHolder(val binding: HomeRecViewBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {
val binding = HomeRecViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MainViewHolder(binding)
}
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
val articles_ = articles[position]
holder.binding.artical = articles_
}
class DiffUtil : androidx.recyclerview.widget.DiffUtil.ItemCallback<Article>() {
override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
return oldItem == newItem
}
}
}
my ViewModel is given below
val article : LiveData<NewsModel>
get() = repoHelper.article
my main Activity
class TestActivity : AppCompatActivity() {
lateinit var binding: ActivityTestBinding
lateinit var mainViewModel: MainViewModel
lateinit var article_: List<Article>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.activity_test)
article_ = ArrayList()
val mainAdapter = MainAdapter(this,article_)
binding.recView.apply {
this.layoutManager = LinearLayoutManager(this@TestActivity)
this.adapter = mainAdapter
}
val apiHelper = RetrofitHelper.getInstance().create(ApiHelper::class.java)
val database_ = DBHelper.getDatabase(applicationContext)
val repoHelper = RepoHelper(apiHelper,database_,applicationContext)
mainViewModel = ViewModelProvider(this,ViewModelFactory(repoHelper)).get(MainViewModel::class.java)
mainViewModel.article.observe(this, Observer {
Log.d("list_of_article",it.articles.toString())
mainAdapter.submitList(it.articles)
})
}
what's the main cause for this error and how do I resolve it.
article_ = ArrayList()
val mainAdapter = MainAdapter(this,article_)
Here you provide an empty list to the Adapter.
After this never changes!
mainAdapter.submitList(it.articles)
does not set this list in the adapter.
So val articles_ = articles[position]
will try to access something from an empty list.
As a matter of fact. You don't even need to have this list at all. ListAdapter has methods to access the list you provide with submitList
Instead of
val articles_ = articles[position]
you can do
val articles_ = getItem(position)
and then you can remove the articles completely there so change
class MainAdapter(private val context: Context,private val articles:List<Article>)
to
class MainAdapter(private val context: Context)
and change
val mainAdapter = MainAdapter(this,article_)
to
val mainAdapter = MainAdapter(this)