如何在Android中使用RecyclerView适配器

hwamh0ep  于 2023-01-19  发布在  Android
关注(0)|答案(2)|浏览(168)

在我的应用程序中,我想用RecyclerView创建自定义日历。
我写下面的代码,但当显示天到recyclerview适配器显示我强制关闭错误!

我的适配器代码:

class DaysAdapter constructor(val context: Context, private val items: MutableList<DayEntity>) :
    RecyclerView.Adapter<DaysAdapter.ViewHolder>() {

    private val TYPE_HEADER = 0
    private val TYPE_DAY = 1
    private var firstDayDayOfWeek = 0
    private var totalDays = 0

    init {
        firstDayDayOfWeek = items[0].dayOfWeek
        totalDays = items.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ViewHolder(inflater.inflate(R.layout.item_day_new, parent, false))
    }

    override fun getItemCount() = 7 * 7

    override fun getItemViewType(position: Int): Int {
        return if (isPositionHeader(position)) {
            TYPE_HEADER
        } else {
            TYPE_DAY
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        //New position
        var newPosition = position
        newPosition += 6 - (newPosition % 7) * 2
        if (totalDays < position - 6 - firstDayDayOfWeek) {
            return
        }
        //Day
        if (!isPositionHeader(newPosition)) {
            if (newPosition - 7 - firstDayDayOfWeek >= 0) {
                holder.dayTxt.text = items[newPosition - 7 - items[0].dayOfWeek].num
                //Holiday
                if (items[newPosition - 7 - firstDayDayOfWeek].isHoliday) {
                    holder.dayTxt.setTextColor(ContextCompat.getColor(context, R.color.red))
                } else {
                    holder.dayTxt.setTextColor(ContextCompat.getColor(context, R.color.black))
                }
            }
        } else {
            //Header
            holder.dayTxt.text = Constants.FIRST_CHAR_OF_DAYS_OF_WEEK_NAME[newPosition]
        }
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val dayTxt = itemView.findViewById(R.id.dayTxt) as TextView

        @SuppressLint("SetTextI18n")
        fun bind() {

        }
    }

    private fun isPositionHeader(position: Int) = position < 7
}

Logcat中的错误消息:

java.lang.IndexOutOfBoundsException: Index: 34, Size: 30
        at java.util.ArrayList.get(ArrayList.java:437)
        at myapp.mycharts.calendar_my.utils.pages.month.DaysAdapter.onBindViewHolder(DaysAdapter.kt:53)
        at myapp.mycharts.calendar_my.utils.pages.month.DaysAdapter.onBindViewHolder(DaysAdapter.kt:15)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
        at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:572)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
        at androidx.recyclerview.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3686)
        at android.view.View.measure(View.java:23169)

显示此行的错误:

holder.dayTxt.text = items[newPosition - 7 - items[0].dayOfWeek].num

填写天数实体的我的片段代码:

class CalendarMonthFragment : Fragment() {

    private lateinit var binding: FragmentCalendarMonthBinding

    private val utils by lazy { UtilsKotlin.getInstance(requireContext()) }
    private var monthOffset = 0
    private lateinit var persianDate: PersianDate

    private val daysAdapter by lazy { DaysAdapter(requireContext(), daysList) }
    private val daysList = mutableListOf<DayEntity>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = FragmentCalendarMonthBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //Utils
        utils.let { utils ->
            //Persian date
            persianDate = utils.today
            //Init days
            arguments?.let {
                monthOffset = it.getInt(Constants.OFFSET_ARGUMENT)
                daysList.addAll(utils.getDays(monthOffset).toMutableList())
            }
        }
        //Days recyclerview
        daysAdapter.notifyDataSetChanged()
        //InitViews
        binding.apply {
            //Recyclerview
            daysRecyclerview.apply {
                layoutManager = GridLayoutManager(requireContext(), 7)
                adapter = daysAdapter
            }
        }
    }
}

如何修复它并将数据显示到recyclerview中?

9rnv2umw

9rnv2umw1#

您需要为该行holder.dayTxt.text = items[newPosition - 7 - items[0].dayOfWeek].num添加一个防止崩溃的检查

val position = newPosition - 7 - items[0].dayOfWeek

if(position != -1 && position < items.size) {
    holder.dayText.text = items[position].num
}

请尝试以上代码...

moiiocjp

moiiocjp2#

IndexOutOfBounds说,在items中没有这样位置号的元素。首先检查“items”是否包含任何元素,如果是,则检查items[0]是否存在。如果是,则您可以从val resultPos = newPosition - 7 - items[0].dayOfWeek中获得结果号,如果是,则检查items.size > resultPos是否包含此元素。希望它能帮助您。

相关问题