You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView未显示元素问题:随机加载4组键值对失败排查

RecyclerView未显示元素的排查与修复

问题描述

我尝试从单例类ImageStore.kt中随机获取4组键值对,通过适配器PractiseAdapter.kt在PractiseFragment.kt的RecyclerView中展示,但RecyclerView未显示任何元素。相关代码如下:

ImageStore.kt

object ImageStore {

private val _imagesNamesMap = hashMapOf(
     R.drawable.africa to Pair("Africa","Afrika"),
     R.drawable.asia to Pair("Asia","Azija"),
     R.drawable.europe to Pair("Europe","Europa"),
     R.drawable.antartica to Pair("Antarctica","Antarktida"),
     R.drawable.airplane to Pair("Aeroplane","Lėktuvas"),
     R.drawable.apple1 to Pair("Apple","Obuolys"),
     R.drawable.key to Pair("Key","raktas"),
     R.drawable.sleep to Pair("to sleep","miegoti"),
     R.drawable.shopping to Pair("to shop","apsipirkti"),
     R.drawable.cinemascreen to Pair("to watch a movie","Žiūrėti filmą"),
     R.drawable.goshopping to Pair("I go shopping","aš einu apsipirkti"),
     R.drawable.what1 to Pair("What is it?","Kas tai?"),
     R.drawable.japanesefood to Pair("Japanese food","Japonų maistas"),
     R.drawable.hotcoffee to Pair("hot coffee","karšta kava"),
     R.drawable.eat to Pair("to eat","valgyti"),
     R.drawable.ofcourse to Pair("Of course","Žinoma"),
     R.drawable.rice to Pair("rice","ryžiai"),
     R.drawable.soup1 to Pair("soup","sriuba"),
     R.drawable.bread1 to Pair("Bread","Duona"),
     R.drawable.water1 to Pair("water","vanduo"),
     R.drawable.glass1 to Pair("a glass","stiklinė"),
     R.drawable.apple1 to Pair("apple","obuolys"),   
 )
 val imagesNamesMap: Map<Int, Pair<String, String>>
     get() = _imagesNamesMap.toList().shuffled().take(4).toMap()
}

PractiseFragment.kt

val layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false)
        binding.recyclerViewPractise.layoutManager = layoutManager
        

        practiseAdapter = PractiseAdapter(binding.btnShuffle,recyclerViewPractise)

        binding.recyclerViewPractise.adapter = practiseAdapter
        practiseAdapter.initsetRecyclerView(recyclerViewPractise)

PractiseAdapter.kt

@SuppressLint("SuspiciousIndentation")
class PractiseAdapter(
    btnShuffle: AppCompatButton,
    recyclerViewPractise: RecyclerView,
) : RecyclerView.Adapter<PractiseAdapter.PractiseViewHolder>() {

    lateinit var recyclerView: RecyclerView
    private var anyCardIsGreen = false
    private var selectedImageResource = -1
    private var selectedImageName = ""
    private var previousSelectedImageResource = -1
    private var previousSelectedImageName = ""
    var imageResources: MutableList<Int>
    var imageNames1: MutableList<Pair<String,String>>

    init {
        imageResources = mutableListOf()
        imageNames1 = mutableListOf()
            btnShuffle.setOnClickListener {
                shuffleCards()
            }
    }

    private fun shuffleCards() {

        imageResources = ImageStore.imagesNamesMap.keys.toList().shuffleList().toMutableList()

        imageNames1= imageResources.mapNotNull { it ->
            val pair = ImageStore.imagesNamesMap[it]
            pair?.let { Pair(pair.first, pair.second) }
        }.toList().shuffleList().toMutableList()


        // Reset the selected image and name
        selectedImageResource = -1
        selectedImageName = ""
        previousSelectedImageResource = -1
        previousSelectedImageName = ""

        // Reset the background color of cardImage views to white
        resetCardImageBackgroundToWhite()


        notifyDataSetChanged()
    }

    fun initsetRecyclerView(recyclerView: RecyclerView) {
        this.recyclerView = recyclerView
    }

    private fun resetCardImageBackgroundToWhite() {
        // Iterate through the card views and reset the background color of cardImage to white
        for (position in 0 until imageResources.size) {

            val holder = recyclerView.findViewHolderForAdapterPosition(position) as? PractiseViewHolder
            holder?.cardImagePractise?.setCardBackgroundColor(Color.WHITE)
        }
    }

    companion object {
        val GREEN_COLOR = Color.parseColor("#ABEBC6")
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PractiseViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_practise_cards, parent, false)

        return PractiseViewHolder(view)
    }

    override fun getItemCount(): Int = imageResources.size

    override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
        val imageResource = imageResources[position]
        val imageName1 = imageNames1[position]


        holder.imageViewPractise.setImageResource(imageResource)
        holder.textViewPractise.text = imageName1.first
        holder.textViewPractise1.text = imageName1.second

        holder.cardImagePractise.setOnClickListener {
            selectedImageResource = imageResource
            previousSelectedImageResource = selectedImageResource
            selectedImageName = ""
            notifyDataSetChanged()
            holder.cardImagePractise.setCardBackgroundColor(GREEN_COLOR)
        }
        holder.cardTextPractise.setOnClickListener {
            if (selectedImageResource == -1) {
                Toast.makeText(
                    it.context,
                    "Please select an image card first.",
                    Toast.LENGTH_SHORT
                ).show()
            } else {
                selectedImageName = imageNames1[position].first
                previousSelectedImageName = selectedImageName
            }
            notifyDataSetChanged()
        }
        val nameColor = if(imageNames1[position].first ==selectedImageName){
            if(ImageStore.imagesNamesMap[selectedImageResource]?.first==selectedImageName){
                Toast.makeText(
                    holder.itemView.context,
                    "Correct name selected!",
                    Toast.LENGTH_SHORT
                ).show()
                anyCardIsGreen=true
                holder.cardTextPractise.setBackgroundColor(GREEN_COLOR) // Set green background for the name card
                Color.GREEN
            } else {
                Toast.makeText(
                    holder.itemView.context,
                    "Wrong name selected!",
                    Toast.LENGTH_SHORT
                ).show()
                Color.RED
            }
        } else {
              holder.cardTextPractise.setBackgroundColor(Color.WHITE)
              Color.WHITE
        }
        holder.cardTextPractise.setBackgroundColor(nameColor)

        // Check if the card is green and set anyCardIsGreen accordingly

    }
    class PractiseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val cardImagePractise: CardView = itemView.findViewById(R.id.cardImagePractise)
        val cardTextPractise: CardView = itemView.findViewById(R.id.cardTextPractise)
        val imageViewPractise: ImageView = itemView.findViewById(R.id.imageViewPractise)
        val textViewPractise: TextView = itemView.findViewById(R.id.textViewPractise)
        val textViewPractise1: TextView = itemView.findViewById(R.id.textViewPractise1)

    }
}

排查到的核心问题

  • 初始数据为空:适配器初始化时imageResources和imageNames1是空列表,且只有点击btnShuffle才会填充数据,Fragment初始化后未主动触发数据加载,导致getItemCount()返回0,RecyclerView无元素可展示。
  • 数据不匹配:ImageStore.imagesNamesMap的getter每次调用都会生成新的随机4项,shuffleCards()中先后两次调用该属性,导致第二次获取的map和第一次的key不匹配,imageNames1可能出现空值或数据量不足。
  • 自定义shuffleList()存在不确定性:未提供该方法实现,若实现错误会导致数据打乱失败,影响数据展示。

修复方案

1. 初始化时主动加载数据

在适配器的init块末尾添加shuffleCards()调用,确保Fragment初始化后立即填充数据:

init {
    imageResources = mutableListOf()
    imageNames1 = mutableListOf()
    btnShuffle.setOnClickListener {
        shuffleCards()
    }
    // 主动触发一次数据加载
    shuffleCards()
}

2. 修正数据获取逻辑,避免重复随机

修改shuffleCards(),只获取一次随机map,再基于该map处理数据,保证key和value匹配:

private fun shuffleCards() {
    // 仅获取一次随机4项数据
    val randomImagesMap = ImageStore.imagesNamesMap
    // 打乱图片资源列表
    imageResources = randomImagesMap.keys.toMutableList().apply { shuffle() }
    // 打乱名称列表
    imageNames1 = randomImagesMap.values.toMutableList().apply { shuffle() }

    // 重置选中状态
    selectedImageResource = -1
    selectedImageName = ""
    previousSelectedImageResource = -1
    previousSelectedImageName = ""

    resetCardImageBackgroundToWhite()
    notifyDataSetChanged()
}

3. 确保shuffleList()正确实现

如果是自定义扩展函数,替换为Kotlin标准库的shuffled()方法,或确保实现正确:

// 移除自定义shuffleList(),直接使用标准方法
imageResources = randomImagesMap.keys.toList().shuffled().toMutableList()

4. 确认RecyclerView视图绑定正确

检查Fragment中recyclerViewPractise是否通过binding获取,避免使用未绑定的视图:

practiseAdapter = PractiseAdapter(binding.btnShuffle, binding.recyclerViewPractise)
binding.recyclerViewPractise.adapter = practiseAdapter
practiseAdapter.initsetRecyclerView(binding.recyclerViewPractise)

内容的提问来源于stack exchange,提问作者kolmikaelson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:32:31