Binding two NumberPicker views to onValueChanged results in unpredictable crashes

I created a dialog containing two NumberPicker views. The first contains a list of groups, the second contains elements 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 connect to 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 a group several times can cause the NumberPicker class to crash when setting setDisplayedValues ​​strings.

The error is the exception of the index of the out of bounds array in the numberpicker element for the elements, the string to which I passed the array of strings. I set a breakpoint in the above update and checked that the String array is always the right size for the number of elements set between the minimum and maximum value in the number picker, so that puzzled 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 going to start reading what is happening in NumberPicker to find out if I am using it incorrectly, but any suggestions would be welcome. The "makeCachedScrollSelectorValue" makes me think that 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 understand that NumberPicker is not really a string collector, so if anyone has a better suggestion on how to achieve such a user interface, I’m all ears. Otherwise, I am heading along the path of trying to implement some kind of debouncer in order to update the item collector as soon as all activity in the group is completed.

+7
android
source share
2 answers

This happens when you repeatedly setDisplayedValue (String []).

when the next line [] is longer than the current getMaxValue (), an exception occurs!

My decision

using

 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); 
+7
source share

If you use indexes starting with 1, use:

  int size = mData.getItemsForGroup(to-1).size(); 

Use this to change the second selector (if the current value is above the maximum, it will set it to a 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 using values ​​as indices, i.e.

  minValue=0 maxValue=strings.length-1 
+1
source share

All Articles