如何根据一个NumberPicker的值改变另一个NumberPicker的选项值
问题分析与修复
崩溃的核心原因有两个:
- 初始化
chordTypePicker时,错误地将maxValue设为chordValues.size - 1(即6),但如果chordTypeValues的元素数量不是7,会直接触发选项数量不匹配的异常。 - 切换和弦类型列表时,未处理当前选中的索引:比如之前选中了第9个位置(对应默认列表里的
#7),切换到E/B的列表时,新的maxValue是7,旧索引超出范围会引发数组越界崩溃。
修复步骤
- 提前初始化
chordTypeValues的默认值,避免未定义状态 - 初始化
chordTypePicker时,用chordTypeValues的长度设置maxValue,保证显示选项数量与范围匹配 - 切换列表前,先将
chordTypePicker的选中位置重置到0(或新列表的有效索引范围内),防止越界
修复后的完整代码
val chordPicker = findViewById<NumberPicker>(R.id.number_picker) val chordImage = findViewById<ImageView>(R.id.chordImage) val chordValues = arrayOf("C", "D", "E", "F", "G", "A", "B") var chordValue = chordValues[0] chordPicker.displayedValues = chordValues chordPicker.minValue = 0 chordPicker.maxValue = chordValues.size - 1 // 初始化默认和弦类型列表 var chordTypeValues = arrayOf("M", "m", "7", "m7", "dim", "maj7", "m6", "aug", "#", "#7") val chordTypePicker = findViewById<NumberPicker>(R.id.number_picker2) // 用和弦类型列表的长度设置maxValue,保证数量匹配 chordTypePicker.minValue = 0 chordTypePicker.maxValue = chordTypeValues.size - 1 chordTypePicker.displayedValues = chordTypeValues chordPicker.setOnValueChangedListener { picker, oldVal, newVal -> chordValue = chordValues[newVal] val newList: Array<String> = if (chordValue == "E" || chordValue == "B") { arrayOf("M", "m", "7", "m7", "dim", "maj7", "m6", "aug") } else { arrayOf("M", "m", "7", "m7", "dim", "maj7", "m6", "aug", "#", "#7") } chordTypeValues = newList // 先重置选中位置到0,避免旧索引超出新列表范围 chordTypePicker.value = 0 // 按顺序设置范围与显示值:先min/max,再displayedValues chordTypePicker.minValue = 0 chordTypePicker.maxValue = newList.size - 1 chordTypePicker.displayedValues = newList }
额外注意
NumberPicker要求displayedValues的数组长度必须等于maxValue - minValue + 1,初始化和切换时都要保证这个对应关系,否则会直接崩溃。
内容的提问来源于stack exchange,提问作者Delirium1608
相关产品推荐
相关产品推荐

