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

如何根据游戏关卡完成状态设置RecyclerView项的可点击性?

实现RecyclerView递进解锁关卡列表的方案

1. 先定义关卡数据模型

创建一个简单的数据类,存关卡的核心状态:

data class Level(
    val id: Int, // 关卡ID,从1开始计数
    val name: String, // 比如"关卡1"
    val isCompleted: Boolean, // 是否通关
    var isLocked: Boolean // 是否锁定,后续逻辑控制
)

2. 初始化关卡列表并计算锁定状态

核心逻辑是只有前一关完成,当前关才解锁,初始化时直接按这个规则生成列表:

fun initLevelList(): List<Level> {
    // 先创建基础关卡数据,第一关默认解锁
    val levels = mutableListOf(
        Level(1, "关卡1", isCompleted = false, isLocked = false),
        Level(2, "关卡2", isCompleted = false, isLocked = true),
        Level(3, "关卡3", isCompleted = false, isLocked = true),
        // 按需添加更多关卡
    )

    // 遍历更新锁定状态(从第二关开始)
    for (i in 1 until levels.size) {
        val prevLevel = levels[i-1]
        // 前一关没完成,当前关就锁定;反之解锁
        levels[i].isLocked = !prevLevel.isCompleted
    }
    return levels
}

3. 实现RecyclerView的Adapter

Adapter负责根据关卡状态渲染UI,锁定的关卡置灰、不可点击,完成的关卡显示通关标识:

3.1 ViewHolder定义

class LevelViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val tvLevelName: TextView = itemView.findViewById(R.id.tv_level_name)
    val ivLock: ImageView = itemView.findViewById(R.id.iv_lock)
    val ivCompleted: ImageView = itemView.findViewById(R.id.iv_completed)
    val levelCard: CardView = itemView.findViewById(R.id.level_card)
}

3.2 Adapter核心代码

class LevelAdapter(
    private val levels: MutableList<Level>,
    private val onLevelClick: (Level) -> Unit
) : RecyclerView.Adapter<LevelViewHolder>() {

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

    override fun onBindViewHolder(holder: LevelViewHolder, position: Int) {
        val level = levels[position]

        holder.tvLevelName.text = level.name

        // 根据状态切换UI
        if (level.isLocked) {
            holder.ivLock.visibility = View.VISIBLE
            holder.ivCompleted.visibility = View.GONE
            holder.levelCard.alpha = 0.5f // 置灰
            holder.levelCard.isClickable = false // 锁定时禁止点击
        } else {
            holder.ivLock.visibility = View.GONE
            holder.ivCompleted.visibility = if (level.isCompleted) View.VISIBLE else View.GONE
            holder.levelCard.alpha = 1.0f
            holder.levelCard.isClickable = true
        }

        // 关卡点击事件
        holder.levelCard.setOnClickListener {
            onLevelClick(level)
        }
    }

    override fun getItemCount() = levels.size

    // 更新关卡状态后刷新列表,同时解锁下一关(如果当前关卡完成)
    fun updateLevel(updatedLevel: Level) {
        val index = levels.indexOfFirst { it.id == updatedLevel.id }
        if (index != -1) {
            levels[index] = updatedLevel
            // 当前关卡完成,且不是最后一关时,解锁下一关
            if (updatedLevel.isCompleted && index < levels.size - 1) {
                val nextLevel = levels[index + 1]
                nextLevel.isLocked = false
                notifyItemChanged(index + 1)
            }
            notifyItemChanged(index)
        }
    }
}

4. 关卡项布局(item_level.xml)

简单的横向布局示例,可根据需求调整样式:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:orientation="horizontal"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tv_level_name"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:textSize="18sp"/>

    <ImageView
        android:id="@+id/iv_lock"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/ic_lock"
        android:visibility="gone"/>

    <ImageView
        android:id="@+id/iv_completed"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/ic_check"
        android:visibility="gone"/>
</LinearLayout>

5. 在Activity/Fragment中使用

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: LevelAdapter
    private lateinit var levelList: MutableList<Level>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recycler_view)
        levelList = initLevelList().toMutableList()
        adapter = LevelAdapter(levelList) { level ->
            // 这里处理关卡点击逻辑,比如跳转到游戏界面
            // 假设游戏结束后,标记当前关卡为完成
            val updatedLevel = level.copy(isCompleted = true)
            // 保存通关状态到本地,避免重启丢失
            saveCompletedLevel(updatedLevel.id)
            adapter.updateLevel(updatedLevel)
        }

        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)
    }

    // 从SharedPreferences读取已通关关卡,初始化时恢复进度
    private fun initLevelList(): List<Level> {
        val savedCompleted = getSharedPreferences("GameData", MODE_PRIVATE)
            .getStringSet("completedLevels", emptySet()) ?: emptySet()

        val levels = mutableListOf<Level>()
        for (i in 1..10) { // 假设有10个关卡
            val isCompleted = savedCompleted.contains(i.toString())
            levels.add(Level(i, "关卡$i", isCompleted, isLocked = false))
        }

        // 重新计算锁定状态
        for (i in 1 until levels.size) {
            levels[i].isLocked = !levels[i-1].isCompleted
        }
        return levels
    }

    // 保存已通关关卡到本地
    private fun saveCompletedLevel(levelId: Int) {
        val sharedPref = getSharedPreferences("GameData", MODE_PRIVATE)
        val completedSet = sharedPref.getStringSet("completedLevels", mutableSetOf()) ?: mutableSetOf()
        completedSet.add(levelId.toString())
        sharedPref.edit().putStringSet("completedLevels", completedSet).apply()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:15:22