How do i change the Android TimePicker minute intervals?

后端 未结 6 1400
小鲜肉
小鲜肉 2020-12-15 14:36

I am writing an application where the user needs to specify a given point in time, but i can\'t seem to figure out how to set the minute values that the user can choose from

相关标签:
6条回答
  • 2020-12-15 14:46

    You can do this programmatically.

    pickStartTime = (TimePicker)findViewById(R.id.StartTime);
    pickStartTime.setOnTimeChangedListener(mStartTimeChangedListener);
    int nextMinute = 0;
    

    Next, Set the OnTimeChangedListener as shown below

    private TimePicker.OnTimeChangedListener mStartTimeChangedListener =
        new TimePicker.OnTimeChangedListener() {
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                updateDisplay(view, startDate, hourOfDay, minute);          
            }
        };
    
    private TimePicker.OnTimeChangedListener mNullTimeChangedListener =
        new TimePicker.OnTimeChangedListener() {
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {}
        };
    

    And,

    private void updateDisplay(TimePicker timePicker, Date date, int hourOfDay, int minute) 
    { 
        nextMinute = nextMinute+5;
    
        // remove ontimechangedlistener to prevent stackoverflow/infinite loop
        timePicker.setOnTimeChangedListener(mNullTimeChangedListener);
    
        // set minute
        timePicker.setCurrentMinute(nextMinute);
    
        // look up ontimechangedlistener again
        timePicker.setOnTimeChangedListener(mStartTimeChangedListener);
    
        // update the date variable for use elsewhere in code
        date.setMinutes(nextMinute);  
    }
    
    0 讨论(0)
  • 2020-12-15 14:52

    all relative answer need you to set an OnTimeChangedListener. My resolution is that you extends android TimePicker,and modify the constructor of it:

        // minute
        mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
        mMinuteSpinner.setMinValue(0);
        mMinuteSpinner.setMaxValue(3);
        mMinuteSpinner.setDisplayedValues(new String[]{"0", "15", "30", "45"});
        mMinuteSpinner.setOnLongPressUpdateInterval(100);
        mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
    

    so you can have the interval you want.

    0 讨论(0)
  • 2020-12-15 14:58

    As a follow up on @Andrey Kotlin solution, you can make it extensible to specify any given minute interval. Also, using kotlin ranges and step keyword, you can have a bit fancier code:

    private fun setupMinutesPicker(minVal: Int, maxVal: Int) {
        minsNumberPicker.displayedValues = null
    
        minsNumberPicker.minValue = minVal / MINUTE_INTERVAL_STEP
        minsNumberPicker.maxValue = maxVal / MINUTE_INTERVAL_STEP
    
        minsNumberPicker.displayedValues = (minVal..maxVal step MINUTE_INTERVAL_STEP)
            .toList()
            .map { mins -> FORMATTER.format(mins) }
            .toTypedArray()
    }
    
    0 讨论(0)
  • 2020-12-15 15:00

    To ensure you're compatible with API 21+, make sure your TimePicker has the following attribute:

    android:timePickerMode="spinner"
    

    Then here's how you can set an interval programmatically. This method falls back on the standard TimePicker if the minute field cannot be found:

    private static final int INTERVAL = 5;
    private static final DecimalFormat FORMATTER = new DecimalFormat("00");
    
    private TimePicker picker; // set in onCreate
    private NumberPicker minutePicker;
    
    public void setMinutePicker() {
        int numValues = 60 / INTERVAL;
        String[] displayedValues = new String[numValues];
        for (int i = 0; i < numValues; i++) {
            displayedValues[i] = FORMATTER.format(i * INTERVAL);
        }
    
        View minute = picker.findViewById(Resources.getSystem().getIdentifier("minute", "id", "android"));
        if ((minute != null) && (minute instanceof NumberPicker)) {
            minutePicker = (NumberPicker) minute;
            minutePicker.setMinValue(0);
            minutePicker.setMaxValue(numValues - 1);
            minutePicker.setDisplayedValues(displayedValues);
        }
    }
    
    public int getMinute() {
        if (minutePicker != null) {
            return (minutePicker.getValue() * INTERVAL);
        } else {
            return picker.getCurrentMinute();
        }
    }
    
    0 讨论(0)
  • 2020-12-15 15:02

    Thanks @Quaffffdd, this is the code in Kotlin

    private val INTERVAL = 5
    
    
    private val FORMATTER = DecimalFormat("00")
    
      private var picker: TimePicker? = null // set in onCreate
      private var minutePicker: NumberPicker? = null
    
      fun setMinutePicker() {
        val numValues = 60 / INTERVAL
        val displayedValues = arrayOfNulls<String>(numValues)
        for (i in 0 until numValues) {
          displayedValues[i] = FORMATTER.format(i * INTERVAL)
        }
    
        val minute = picker?.findViewById<NumberPicker>(Resources.getSystem().getIdentifier("minute", "id", "android"))
        if (minute != null) {
          minutePicker = minute
          minutePicker!!.minValue = 0
          minutePicker!!.maxValue = numValues - 1
          minutePicker!!.displayedValues = displayedValues
        }
      }
    
      fun getMinute(): Int {
        return if (minutePicker != null) {
          minutePicker!!.getValue() * INTERVAL
        } else {
          picker!!.currentMinute
        }
      }
    
    0 讨论(0)
  • 2020-12-15 15:06

    After searching the net, I didn't find the simplest solution.
    So I decided to share:
    You can use reflections!
    The following code use intervals of 10 minutes, but you can choose the minutes you want to use in the DISPLAYED_MINS array.

    private final static String[] DISPLAYED_MINS = { "0", "10", "20", "30", "40", "50" };
    
    private NumberPicker getMinuteSpinner(TimePicker t)
    {
        try
        {
            Field f = t.getClass().getDeclaredField("mMinuteSpinner"); // NoSuchFieldException
            f.setAccessible(true);
            return (NumberPicker) f.get(t); // IllegalAccessException
        }
        catch (Exception e)
        {
            Log.e("timepicker","field name has been changed, check grepcode");
            return null;
        }
    }
    

    when you create your timepicker:

    final TimePicker dpStartDate = (TimePicker) view.findViewById(R.id.dpStartDate);
    NumberPicker startMinSpiner = getMinuteSpinner(dpStartDate);
    if (null != startMinSpiner)
    {
        startMinSpiner.setMinValue(0);
        startMinSpiner.setMaxValue(DISPLAYED_MINS.length - 1);
        startMinSpiner.setDisplayedValues(DISPLAYED_MINS);
    }
    

    Just don't forget that getCurrentMinute() return the selected minute in the DISPLAY_MINS array. in order to get the minute:

    int theTime = 0;
    for (String number: DISPLAYED_MINS) {
        int theNumber = Integer.parseInt(number);
        if (theNumber % 5 != 0) {
            theNumber = ((int)(theNumber / 5)) * 5;
        }
        if (theNumber == dpStartDate.getCurrentMinute()) {
            theTime = theNumber;
            break;
        }
    }
    
    0 讨论(0)
提交回复
热议问题