kotlin recyclerview MVVM 错误 - IndexOutOfBoundsException

kotlin recyclerview MVVM error - IndexOutOfBoundsException

我在 recyclerview 上设置一个列表,使用 MVVM 时出现错误, IndexOutOfBoundsException。 我用于 recyclerview 适配器的代码如下 - onBindViewHolder 是我设置 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
        }

    }
}

下面给出了我的 ViewModel

  val article : LiveData<NewsModel>
    get() = repoHelper.article

我的主要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)
        })
    }

此错误的主要原因是什么以及如何解决它。

答案:

您没有实施 getItemCount()。它 returns 列表的大小。

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

IndexOutOfBoundsException 的原因 是您试图访问超出列表大小的列表索引。

示例:

列表的大小为 2。因此元素将位于索引 0 和 1。如果您尝试访问索引 2,那么您将看到 IndexOutOfBoundsException

article_ = ArrayList()
val mainAdapter = MainAdapter(this,article_)

此处您向适配器提供了一个空列表。

此后永不改变!

mainAdapter.submitList(it.articles) 未在适配器中设置此列表。

因此 val articles_ = articles[position] 将尝试访问空列表中的内容。

事实上。您甚至根本不需要这个列表。 ListAdapter 具有访问您提供的列表的方法 submitList

而不是

val articles_ = articles[position]

你可以做到

val articles_ = getItem(position)

然后你可以完全删除那里的文章所以改变

class MainAdapter(private val context: Context,private val articles:List<Article>)

class MainAdapter(private val context: Context)

并改变

val mainAdapter = MainAdapter(this,article_)

val mainAdapter = MainAdapter(this)