将两个NumberPicker视图与onValueChanged链接会导致不可预测的崩溃

Sha*_*aun 7 android

我创建了一个包含两个NumberPicker视图的对话框.第一个包含组列表,第二个包含所选组中的项目:

Group         Group Items
  1            2: Group 2 Item 2
 [2]          [3: Group 2 Item 3]
  3            4: Group 2 Item 4
Run Code Online (Sandbox Code Playgroud)

我正在第一个NumberPicker中插入setOnValueChangedListener来填充第二个NumberPicker.

  mNumberPickerGroup.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker numberPicker, int from, int to) {
            int size = mData.getItemsForGroup(to).size();
            String[] strings = mData.getItemTitlesForGroup(to);

            mNumberPickerItems.setMinValue(1);
            mNumberPickerItems.setValue(1);

            mNumberPickerItems.setMaxValue(size);
            mNumberPickerItems.setDisplayedValues(strings);

        }
    });
Run Code Online (Sandbox Code Playgroud)

这基本上有效 - 直到在某些情况下,在设置setDisplayedValues字符串时,更改组几次可能会导致NumberPicker类崩溃.

这个错误是项目的numberpicker中的数组索引超出范围异常,是我传入的字符串数组的一行.我在上面的更新代码中设置了一个断点,并验证了String数组始终是数字选择器上最小值和最大值之间设置的项目数量的正确大小,所以这让我很难过.

  java.lang.ArrayIndexOutOfBoundsException: length=22; index=22
        at android.widget.NumberPicker.ensureCachedScrollSelectorValue(NumberPicker.java:1768)
        at android.widget.NumberPicker.initializeSelectorWheelIndices(NumberPicker.java:1583)
        at android.widget.NumberPicker.setMaxValue(NumberPicker.java:1390)
        at uk.co.my.app.fragments.GroupMarkUptoDialog.updateItemPicker(MarkUptoDialog.java:99)
Run Code Online (Sandbox Code Playgroud)

我即将开始阅读NumberPicker中发生的事情,以确定我是否使用它错了,但任何建议都会受到欢迎."ensureCachedScrollSelectorValue"让我觉得我需要在用新数据更新之前以某种方式重置numberpicker,但我不确定.

谁能看到我在这里做错了什么?

我意识到NumberPicker并不是一个真正的字符串选择器,所以如果有人对如何实现这种UI有更好的建议,我会全力以赴.否则,我正在试图实施某种去抖动的路线,在群组选择器上的所有活动完成后更新项目选择器.

Nin*_*nja 10

当你多次使用setDisplayedValue(String [])时会发生这种情况.

当下一个string []的长度比当前的getMaxValue()大时,Exception会发生!

我的解决方案

使用

picker.setMaxValue(0);
Run Code Online (Sandbox Code Playgroud)

之前

picker.setDisplayedValues(stringArr);
Run Code Online (Sandbox Code Playgroud)

我的代码

cityPicker.setMaxValue(0);
    try {
        cityPicker.setDisplayedValues(citySet.toArray(new String[citySet.size()]));
    } catch (Exception e) {
        Log.e("Ninja", "cityPicker.setDisplayedValues(citys) occurs Error. province is " + province);
    }
    cityPicker.setMaxValue(citySet.size() - 1);
Run Code Online (Sandbox Code Playgroud)