I've created a dialog containing two NumberPicker views. The first contains a list of groups, the second contains the items from the selected group:
Group Group Items
1 2: Group 2 Item 2
[2] [3: Group 2 Item 3]
3 4: Group 2 Item 4
I'm hooking in to the setOnValueChangedListener in the first NumberPicker to populate the second 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);
}
});
This basically works - until, in certain circumstances, changing the group a few times can cause a crash in the NumberPicker class, when setting the setDisplayedValues strings.
The error is an array index out of bounds exception in the numberpicker for items, a line to do with the string array I passed in. I've set a break point in the update code above, and verified that the String array is always the correct size for the number of items set between min and max value on the number picker, so this has stumped me.
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)
I'm about to start reading through what happens in the NumberPicker to figure out if I'm using it wrong, but any suggestions would be welcome. "ensureCachedScrollSelectorValue" makes me think I need to reset the numberpicker somehow before updating it with new data but I'm not sure.
Can anyone see what I'm doing wrong here?
I realise the NumberPicker is not really a String picker, so if anyone has a better suggestion for how to achieve this sort of UI I'm all ears. Otherwise, I'm heading down the route of trying to implement some kind of debouncer, to update the items picker once all activity on the group picker is complete.
It happens when you setDisplayedValue(String[]) many times.
If the string[]'s length is larger than the current getMaxValue(), Exception happens!
My solution
use
picker.setMaxValue(0);
before
picker.setDisplayedValues(stringArr);
My code
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);
If you use indexes started from 1 then use:
int size = mData.getItemsForGroup(to-1).size();
Use this to change second picker (if current value is above maximum it will set it to new maximum):
int i = mNumberPickerItems.getValue();
int max = strings.length;
if (i > max)
i = max;
mNumberPickerItems.setMinValue(1);
mNumberPickerItems.setMaxValue(1);
mNumberPickerItems.setDisplayedValues(strings);
mNumberPickerItems.setMaxValue(max);
mNumberPickerItems.setValue(i);
And try to use values as indexes, i.e.
minValue=0
maxValue=strings.length-1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With