kotlin 在实现带复选框的Android Recycler View时出现“空列表不包含索引0处的元素”错误

xtfmy6hx  于 7个月前  发布在  Kotlin
关注(0)|答案(2)|浏览(86)

我正在实现一个回收器视图,它的项目作为复选框。我的数据来自ROOM数据库,这个回收器视图是在一个对话框片段。
对话片段:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = ScheduleFloorDialogBinding.inflate(layoutInflater)
        createProfileViewModel = CreateProfileViewModel(Application())
        floorProfileDialogAdapter = FloorProfileDialogAdapter()

        binding.rvFloorsForScheduling.layoutManager = LinearLayoutManager(requireActivity())
        binding.rvFloorsForScheduling.adapter = floorProfileDialogAdapter

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val floorList: MutableList<String> = mutableListOf()

        //Getting list of all floors
        createProfileViewModel.totalFloors.observe(viewLifecycleOwner) {
            Timber.d("List of floors received : $it")

            val intList = it.map(String::toInt)
            val maxFloorValue = intList.last()
            var count = 0

            try {
                while (count <= maxFloorValue) {
                    floorList.add(count.toString())
                    count++
                }
            } catch (e: Exception) {
                Timber.d("Exception: $e")
            }
            floorProfileDialogAdapter.getAllFloors(floorList)
            Timber.d("Floor List : $floorList")
        }
    }

字符串
我可以从这里发送数据列表到我的适配器。
适配器:

class FloorProfileDialogAdapter() : RecyclerView.Adapter<FloorProfileDialogAdapter.MyViewHolder>() {

    var floors = emptyList<String>()

    inner class MyViewHolder(val binding: ScheduleFloorDialogItemBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = ScheduleFloorDialogItemBinding.inflate(inflater, parent, false)

        return MyViewHolder(binding)
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val currentFloor = floors[position]
        Timber.d("Current floor: $currentFloor")
        holder.binding.floorCheckBox.text = "Floor $currentFloor"
    }

    override fun getItemCount(): Int {
        return floors.toString().length
    }

    fun getAllFloors(floorsReceived: List<String>) {
        Timber.d("Floors received : $floorsReceived")
        this.floors = floorsReceived
    }
}


Adapter的getAllFloor方法中的Log显示已收到列表:


的数据

但是在onBindViewHolder()内部,当我使用position时,我得到错误:

java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0.

hsvhsicv

hsvhsicv1#

当你用一个空列表初始化floorProfileDialogAdapter时,视图已经膨胀了,直到你使用notifyDataSetChange()它才被改变,这是一个不推荐的解决方案。
或者使用Androidx Recycler view Package中的ListAdapter:它有自己的提交列表,因此每次您提交列表时,它都会通知数据集更改,并将其与前一个列表进行比较
Check documentation

u2nhd7ah

u2nhd7ah2#

在我的例子中,我用PagingDataAdapter替换了一个常用的自定义适配器。错误“java.lang.IndexOutOfBoundsException:Empty list doesn't contain element at index 0.”发生在onBindViewHolder中:

var items: List<Item> = emptyList()

override fun onBindViewHolder(holder: SomeViewHolder<*>, position: Int) {
    val item = items[position]

字符串
创建适配器后,items集合没有填充。然后我替换为:

override fun onBindViewHolder(holder: SomeViewHolder<*>, position: Int) {
    val item = getItem(position)

相关问题