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:
- Cambiar la velocidad de lanzamiento de Android Numberpicker dentro de un Alertdialog
- Bloquear la transición entre el valor mínimo y el valor máximo en NumberPicker
- NumberPicker no se muestra en AlertDialog
- Cómo utilizar selector de números con el cuadro de diálogo
- ¿Cómo utilizar NumberPicker en la aplicación de Android con API 7?
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?
- Cómo reducir el tamaño de fuente en NumberPicker
- Capturar teclado 'Hecho' para NumberPicker
- AlertDialog con NumberPicker procesado incorrectamente
- ¿Cómo se muestra un NumberPicker de 2 dígitos en android?
- NPE en ChangeCurrentByOneFromLongPressCommand (en dispositivos Samsung con Android 4.3)
- Android NumberPicker envuelve valores cuando se cambian los valores mostrados
- ¿Cómo saltar un número de selector de números?
- El valor predeterminado de Android Numberpicker no viene
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.
- La SOAPAction dada no coincide con una operación
- La mejor manera de hacer la aplicación cross-mobile