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)
我在 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)