Khushbu
Khushbu

Reputation: 88

kotlin recyclerview MVVM error - IndexOutOfBoundsException

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.

Upvotes: 0

Views: 327

Answers (2)

Ivo
Ivo

Reputation: 23357

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)

Upvotes: 1

Kamal Nayan
Kamal Nayan

Reputation: 1718

Answer:

You are not implementing the getItemCount(). It returns the size of the list.

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

Cause of IndexOutOfBoundsException is that you are trying to access the index of list which is beyond the size of list.

Example:

The size of list is 2. So the elements will be at index 0 and 1. If you try to access index 2 then you will get to see IndexOutOfBoundsException

Upvotes: 0

Related Questions