Cómo restablecer los datos de NumberPicker

Estoy usando dos NumberPickers para mostrar los datos de la provincia ( mProvincePicker ) y de la ciudad ( mCityPicker ) en mi aplicación. Cuando el usuario cambia los datos de la provincia, los datos de la ciudad deben cambiarse en consecuencia. Restablecer los datos de NumberPicker.onValueChange(NumberPicker picker, int oldVal, int newVal) en NumberPicker.onValueChange(NumberPicker picker, int oldVal, int newVal) . Pero no funciona bien y una java.lang.ArrayIndexOutOfBoundsException bloquea la aplicación.

Aquí está mi código:

 public class AreaPickerDialog extends Dialog implements OnValueChangeListener, OnClickListener { static final String TAG = "AreaPickerDialog"; private NumberPicker mProvincePicker; private NumberPicker mCityPicker; private Button mCancelBtn; private Button mOKBtn; private AreaUtil mAreaUtil; private List<Area> mProvinces; private int mAreaId; private int mProvinceId; private Handler mHandler; public AreaPickerDialog(Context context, Handler handler, int areaId) { super(context); mAreaUtil = AreaUtil.getInstance(); mProvinces = mAreaUtil.getProvinceList(); mAreaId = areaId; mProvinceId = mAreaUtil.getProvinceIdByAreaId(areaId); mHandler = handler; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_area_picker); mProvincePicker = (NumberPicker) findViewById(R.id.np_province); mCityPicker = (NumberPicker) findViewById(R.id.np_city); mCancelBtn = (Button) findViewById(R.id.btn_cancel); mOKBtn = (Button) findViewById(R.id.btn_ok); initProvinceData(); mProvincePicker.setOnValueChangedListener(this); mCityPicker.setOnValueChangedListener(this); mCancelBtn.setOnClickListener(this); mOKBtn.setOnClickListener(this); } private void initProvinceData() { if (mProvinces != null && mProvinces.size() > 0) { String[] provinceNames = new String[mProvinces.size()]; for (int i = 0; i < provinceNames.length; i++) { provinceNames[i] = mProvinces.get(i).getProvincename(); } mProvincePicker.setDisplayedValues(provinceNames ); mProvincePicker.setMinValue(1); mProvincePicker.setMaxValue(mProvinces.size()); } mProvincePicker.setValue(mProvinceId); initCityData(mProvincePicker.getValue()); } private void initCityData(int provinceId) { List<Arealist> cities = mAreaUtil.getCityListOfProvince(provinceId); if (cities != null && cities.size() > 0) { try { int min = Integer.parseInt(cities.get(0).getAreaid()); int max = Integer.parseInt(cities.get(cities.size() -1).getAreaid()); String[] cityNames = new String[cities.size()]; for (int i = 0; i < cityNames.length; i++) { cityNames[i] = cities.get(i).getName(); } mCityPicker.setValue(0); mCityPicker.setDisplayedValues(cityNames); mCityPicker.setMinValue(min); mCityPicker.setMaxValue(max); } catch (NumberFormatException e) { ILog.e(TAG, e.getMessage(), e); } } } @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { if (mProvincePicker.equals(picker)) { initCityData(mProvincePicker.getValue()); } else if (mCityPicker.equals(picker)) { mAreaId = mCityPicker.getValue(); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_cancel: dismiss(); break; case R.id.btn_ok: Message msg = mHandler.obtainMessage(MineActivity.MSG_UPDATE_AREA); msg.arg1 = mAreaId; msg.sendToTarget(); dismiss(); break; default: break; } } } 

Y rastreo de error logcat:

 12-30 23:09:26.560: E/InputEventReceiver(5620): Exception dispatching input event. 12-30 23:09:26.560: W/dalvikvm(5620): threadid=1: thread exiting with uncaught exception (group=0x41ddf438) 12-30 23:09:26.580: E/AndroidRuntime(5620): FATAL EXCEPTION: main 12-30 23:09:26.580: E/AndroidRuntime(5620): java.lang.ArrayIndexOutOfBoundsException: length=14; index=15 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.updateInputTextView(NumberPicker.java:1840) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.setDisplayedValues(NumberPicker.java:1423) 12-30 23:09:26.580: E/AndroidRuntime(5620): at com.meishai.app.dialog.AreaPickerDialog.initCityData(AreaPickerDialog.java:88) 12-30 23:09:26.580: E/AndroidRuntime(5620): at com.meishai.app.dialog.AreaPickerDialog.onValueChange(AreaPickerDialog.java:100) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.notifyChange(NumberPicker.java:1855) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.setValueInternal(NumberPicker.java:1641) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.scrollBy(NumberPicker.java:1106) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.onTouchEvent(NumberPicker.java:886) 12-30 23:09:26.580: E/AndroidRuntime(5620): at android.view.View.dispatchTouchEvent(View.java:7127) 12-30 23:09:26.580: E/AndroidRuntime(5620): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170) 12-30 23:09:26.580: E/AndroidRuntime(5620): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905) 12-30 23:09:26.580: E/AndroidRuntime(5620): at net.simonvt.numberpicker.NumberPicker.dispatchTouchEvent(NumberPicker.java:944) .... 

Estoy minValue,maxValue and DisplayedValues el minValue,maxValue and DisplayedValues para restablecer los datos de NumberPicker y no funciona, así que ¿cuál es el camino correcto?

Compruebe para Call setDisplayedValues(null) antes de setMaxValue en onClick.

Referencia: https://stackoverflow.com/a/24322319/2624806

Tengo el mismo problema y lo arreglé sin modificar NumberPicker.java . Aquí está el código para su referencia.

 private void initCityData(int provinceId) { List<Arealist> cities = mAreaUtil.getCityListOfProvince(provinceId); if (cities != null && cities.size() > 0) { try { int min = Integer.parseInt(cities.get(0).getAreaid()); int max = Integer.parseInt(cities.get(cities.size() -1).getAreaid()); String[] cityNames = new String[cities.size()]; for (int i = 0; i < cityNames.length; i++) { cityNames[i] = cities.get(i).getName(); } int maxV = mCityPicker.getMaxValue(); if (max> maxV){ mCityPicker.setMinValue(min); mCityPicker.setValue(0); mCityPicker.setDisplayedValues(cityNames); mCityPicker.setMaxValue(max); }else{ mCityPicker.setMinValue(min); mCityPicker.setValue(0); mCityPicker.setMaxValue(max); mCityPicker.setDisplayedValues(cityNames); } } catch (NumberFormatException e) { ILog.e(TAG, e.getMessage(), e); } } } 

Bueno, busco en el código fuente de NumberPicker.java , encuentro que volverá a calcular los datos y actualizar la interfaz de usuario en setMinValue(int minValue) y setMaxValue(int minValue) . Cuando se establece el nuevo minValue, se calculará utilizando new minValue y old maxValue, entonces se producirá un error.

Por lo tanto, modificar un poco de la NumberPicker : establecer el valor sólo en setMinValue(int minValue) y setMaxValue(int maxValue) , y actualizar la interfaz de usuario en setDisplayedValues(String[] displayedValues) . Cuando los datos de NumberPicker cambian, simplemente reinicialice los valores minValue, maxVaule y displayValues. Tenga en cuenta que setDisplayedValues(String[] displayedValues) DEBE ser llamado por fin.

Esto es lo que he modificado:

NumberPicker.java :

 public void setMinValue(int minValue) { if (mMinValue == minValue) { return; } if (minValue < 0) { throw new IllegalArgumentException("minValue must be >= 0"); } mMinValue = minValue; if (mMinValue > mValue) { mValue = mMinValue; } //boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length; //setWrapSelectorWheel(wrapSelectorWheel); //initializeSelectorWheelIndices(); //updateInputTextView(); //tryComputeMaxWidth(); invalidate(); } public void setMaxValue(int maxValue) { if (mMaxValue == maxValue) { return; } if (maxValue < 0) { throw new IllegalArgumentException("maxValue must be >= 0"); } mMaxValue = maxValue; if (mMaxValue < mValue) { mValue = mMaxValue; } //boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length; //setWrapSelectorWheel(wrapSelectorWheel); //initializeSelectorWheelIndices(); //updateInputTextView(); //tryComputeMaxWidth(); invalidate(); } public void setDisplayedValues(String[] displayedValues) { if (mDisplayedValues == displayedValues) { return; } mDisplayedValues = displayedValues; if (mDisplayedValues != null) { // Allow text entry rather than strictly numeric entry. mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); } else { mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER); } boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length; setWrapSelectorWheel(wrapSelectorWheel); updateInputTextView(); initializeSelectorWheelIndices(); tryComputeMaxWidth(); } 

AreaPickerDialog.java :

 private void initCityData(int provinceId) { List<Arealist> cities = mAreaUtil.getCityListOfProvince(provinceId); if (cities != null && cities.size() > 0) { try { int min = Integer.parseInt(cities.get(0).getAreaid()); int max = Integer.parseInt(cities.get(cities.size() -1).getAreaid()); String[] cityNames = new String[cities.size()]; for (int i = 0; i < cityNames.length; i++) { cityNames[i] = cities.get(i).getName(); } mCityPicker.setMinValue(min); mCityPicker.setMaxValue(max); mCityPicker.setDisplayedValues(cityNames); } catch (NumberFormatException e) { ILog.e(TAG, e.getMessage(), e); } } } 

Esta es una solución fea pero que funciona.

Buscando el código de NumberPicker que está usando:

 private boolean updateInputTextView() { /* * If we don't have displayed values then use the current number else * find the correct value in the displayed values for the current * number. */ String text = (mDisplayedValues == null) ? formatNumber(mValue) : mDisplayedValues[mValue - mMinValue]; 

Puede ver que está usando mMinValue antes de llamar a setMinValue.

Intente establecer minValue y maxValue, antes de configurar los valores mostrados.

  • Android numberpicker para números de coma flotante
  • Seleccionador de números de Android obtiene valor para textview
  • Modificación o cambio de valores mínimos, máximos y mostrados para NumberPicker
  • Android NumberPicker con Formatter no se formatea en la primera reproducción
  • Android NumberPicker - Números negativos
  • Android NumberPicker, DatePicker, flechas TimePicker están desaparecidas
  • ¿Cómo obtener el número seleccionado de NumberPicker?
  • Implementar OnValueChange a un NumberPicker en Android
  • Configuración de typeFace a NumberPicker
  • Diálogo de PreferenciasActividad de Android con el selector de números
  • Cambio del color del divisor de NumberPicker
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.