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

Kotlin开发Android骰子应用如何动态格式化调用资源ID替代多条件判断

实现方案

下面提供3种常用的可行优化方案,你可以根据自己的需求选择:


方案1:动态通过资源名获取资源ID(最符合你动态格式化调用的需求)

Android 提供了Resources.getIdentifier()方法,可以通过资源名称字符串、资源类型、包名动态查找对应的资源ID,完全不需要写条件判断。
优化后的rollDice代码如下:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    // 按命名规则动态生成资源名
    val resName = "dice_$diceRoll"
    // 动态查找对应drawable的资源ID
    val resId = resources.getIdentifier(resName, "drawable", packageName)
    // 加兜底逻辑避免资源不存在导致崩溃
    diceImage.setImageResource(if (resId != 0) resId else R.drawable.dice_1)
}

优缺点说明:

  • 优点:代码极简,后续如果要扩展骰子面数,只需要添加对应命名的drawable资源即可,不需要修改逻辑代码
  • 缺点:内部通过反射查找资源,有微小的性能损耗,资源名写错时编译期不会报错,运行时才会出现找不到资源的问题

方案2:预定义资源映射表(性能最优,编译安全)

提前把点数和对应的资源ID的映射关系存在集合中,使用时直接通过点数取值,不需要动态查找,性能最好,且编译期就能检查资源是否存在。
首先在MainActivity中定义成员变量存储映射关系:

// 下标对应骰子点数,索引0空置不用
private val diceDrawableIds = intArrayOf(0, R.drawable.dice_1, R.drawable.dice_2, R.drawable.dice_3, R.drawable.dice_4, R.drawable.dice_5, R.drawable.dice_6)

然后修改rollDice方法:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    diceImage.setImageResource(diceDrawableIds[diceRoll])
}

优缺点说明:

  • 优点:性能最高,编译期就能校验资源存在,不会出现运行时找不到资源的问题
  • 缺点:扩展骰子面数时需要手动修改映射表添加新的资源ID

方案3:用when表达式替换if-else(逻辑最直观,适合固定面数场景)

如果不想用上面两种方案,只是想把冗余的if-else简化,可以用Kotlin的when表达式,代码更简洁易读:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    val drawableId = when(diceRoll) {
        1 -> R.drawable.dice_1
        2 -> R.drawable.dice_2
        3 -> R.drawable.dice_3
        4 -> R.drawable.dice_4
        5 -> R.drawable.dice_5
        else -> R.drawable.dice_6
    }
    diceImage.setImageResource(drawableId)
}

优缺点说明:

  • 优点:逻辑直观清晰,编译期安全,不需要额外的反射或者预定义集合
  • 缺点:面数较多时代码会变长,扩展需要手动添加分支

额外优化提示

你可以将ImageView和Button的实例提到类成员变量的位置,避免每次触发点击事件都重复执行findViewById,提升性能:

class MainActivity : AppCompatActivity() {
    private lateinit var diceImage: ImageView
    private lateinit var rollButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        diceImage = findViewById(R.id.imageView)
        rollButton = findViewById(R.id.button)
        rollButton.setOnClickListener { rollDice() }
    }

    // 后续rollDice方法中不需要再执行findViewById
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:03