Search code examples
javaandroidtimepickernumberpicker

Android NumberPicker set number of items to wrap items around


I was trying to set the hour and minute in the TimePicker and I found that it seems that there is a minimum number of items required in the NumberPicker for the values to wrap around.

How do I set the number of items to lesser than the default if I don't have so many values (got only 4: "00", "15", "30" and "45")?

The image below shows the hours as correct but the minutes as wrong. I need the minutes to wrap around (i.e. "45" before "00") like the hours.

enter image description here

Here is my code:

@SuppressLint("NewApi")
private void setTimePickerInterval(TimePicker timePicker) {
    try {
        Class<?> classForid = Class.forName("com.android.internal.R$id");

        Field fieldHr = classForid.getField("hour");
        mHourPicker = (NumberPicker) timePicker.findViewById(fieldHr.getInt(null));

        //set hours from 9am to 7pm (opening hours)
        mHourPicker.setMinValue(0);
        mHourPicker.setMaxValue(10);
        mDisplayedValuesHr = new ArrayList<String>();

        for (int i = 9; i < 20; i++) {
            mDisplayedValuesHr.add(String.format("%02d", i));
        }

        mHourPicker.setDisplayedValues(mDisplayedValuesHr.toArray(new String[0]));

        Field fieldMin = classForid.getField("minute");
        mMinutePicker = (NumberPicker) timePicker.findViewById(fieldMin.getInt(null));

        //set minutes in 15 mins interval
        mMinutePicker.setMinValue(0);
        mMinutePicker.setMaxValue(3);
        mDisplayedValuesMin = new ArrayList<String>();

        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            mDisplayedValuesMin.add(String.format("%02d", i));
        }

        mMinutePicker.setDisplayedValues(mDisplayedValuesMin.toArray(new String[0]));

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Solution

  • You can explicitly call setWrapSelectorWheel (boolean) to trigger the private method updateWrapSelectorWheel of NumberPicker:

    @SuppressLint("NewApi")
    private void setTimePickerInterval(TimePicker timePicker) {
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
    
            Field fieldHr = classForid.getField("hour");
            mHourPicker = (NumberPicker) timePicker.findViewById(fieldHr.getInt(null));
    
            //set hours from 9am to 7pm (opening hours)
            mHourPicker.setMinValue(0);
            mHourPicker.setMaxValue(10);
            mDisplayedValuesHr = new ArrayList<String>();
    
            for (int i = 9; i < 20; i++) {
                mDisplayedValuesHr.add(String.format("%02d", i));
            }
    
            mHourPicker.setDisplayedValues(mDisplayedValuesHr.toArray(new String[0]));
    
            Field fieldMin = classForid.getField("minute");
            mMinutePicker = (NumberPicker) timePicker.findViewById(fieldMin.getInt(null));
    
            //set minutes in 15 mins interval
            mMinutePicker.setMinValue(0);
            mMinutePicker.setMaxValue(3);
            mDisplayedValuesMin = new ArrayList<String>();
    
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                mDisplayedValuesMin.add(String.format("%02d", i));
            }
    
            mMinutePicker.setDisplayedValues(mDisplayedValuesMin.toArray(new String[0]));
            mMinutePicker.setWrapSelectorWheel(true);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }