Show TimePicker with minutes intervals in android
Asked Answered
P

11

58

My application show a TimePickerDialog to set a time. I want that the timePickerDialog show the minutes with an interval of 5 minutes.

This works fine with this code:

private final int TIME_PICKER_INTERVAL=5;
private boolean mIgnoreEvent=false;
…
    public TimePickerDialogs(Context arg0, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
    super(arg0, callBack, hourOfDay, minute, is24HourView);

    formato=Statics.formato;
}

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
    //super.onTimeChanged(arg0, arg1, arg2);

    if (mIgnoreEvent)
        return;
    if (minute%TIME_PICKER_INTERVAL!=0){
        int minuteFloor=minute-(minute%TIME_PICKER_INTERVAL);
        minute=minuteFloor + (minute==minuteFloor+1 ? TIME_PICKER_INTERVAL : 0);
        if (minute==60)
            minute=0;
        mIgnoreEvent=true;
        view.setCurrentMinute(minute);
        mIgnoreEvent=false;
    }
}

Although only minutes can be selected with an interval of five minutes, the timepickerdialog looks like:

hours and minutes

do not know how the minutes also show the range of 5 minutes, as in this picture:

hours and minutes - 5

I have searched but can not find the solution.

Paulsen answered 26/11, 2013 at 10:32 Comment(3)
This should help you out: #16187841Prepossessing
I already knew that answer, the problem is I'm using a timePickerDialog not have a TimePicker in xml to call (... findViewById)Paulsen
In my opinion, all the answers are too complex for something so simple if you do it in a custom layout xml with numberpickers. i just don't see the reason to use a CustomTimePickerDialog for this approachJohst
R
131

Use the following the custom class called CustomTimePickerDialog, which I think solve your problem.

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.widget.NumberPicker;
import android.widget.TimePicker;

public class CustomTimePickerDialog extends TimePickerDialog {

    private final static int TIME_PICKER_INTERVAL = 5;
    private TimePicker mTimePicker;
    private final OnTimeSetListener mTimeSetListener;

    public CustomTimePickerDialog(Context context, OnTimeSetListener listener,
            int hourOfDay, int minute, boolean is24HourView) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, null, hourOfDay,
                minute / TIME_PICKER_INTERVAL, is24HourView);
        mTimeSetListener = listener;
    }

    @Override
    public void updateTime(int hourOfDay, int minuteOfHour) {
        mTimePicker.setCurrentHour(hourOfDay);
        mTimePicker.setCurrentMinute(minuteOfHour / TIME_PICKER_INTERVAL);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case BUTTON_POSITIVE:
                if (mTimeSetListener != null) {
                    mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                            mTimePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
                }
                break;
            case BUTTON_NEGATIVE:
                cancel();
                break;
        }
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            mTimePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker minuteSpinner = (NumberPicker) mTimePicker
                .findViewById(field.getInt(null));
            minuteSpinner.setMinValue(0);
            minuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            minuteSpinner.setDisplayedValues(displayedValues
                    .toArray(new String[displayedValues.size()]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Here is the demonstrating screenshot.

enter image description here

Ruby answered 5/12, 2013 at 9:53 Comment(22)
NumberPicker is not available in pre honeycomb. Suggest me some solution for thatVexatious
This worked perfectly for me, thank you! I modified the constructor to take an interval argument and replaced the TIME_PICKER_INTERVAL constant with an interval variable ... but realistically I don't expect to ever need an interval other than 5.Gass
I works ok for 15 minutes interval but not on 30 minutes intervalMackenie
Ok, I manage to solve the 30 minutes interval by adding a onTimeChanged check with last save hours and minutes. If both are different, it will only change the minutes instead of both of them by using view.setCurrentHour(lastSavedHour). I am not sure if this is a good way of doing it... But if there are better solution do feel free to let me know :)Mackenie
I feel the need to clarify @LeeYiHong's comment because I was confused until I implemented it. It works. It just has an annoying bug. For example if you change from 14:00 to :30, the hour goes back to 13.Alwitt
This piece of code doesn't work for the Android 5.0 version of the TimePickerDialog, since it doesn't use the NumberPicker widget for minute selection.Preshrunk
@LeonLucardie if you change the super call to be super(context, TimePickerDialog.THEME_HOLO_LIGHT, callBack, hourOfDay, minute, is24HourView); it will work with Android 5.0. Passing the theme makes it use the picker style timeDialog. I've submitted an edit to the answer.Chokefull
@LeonLucardie - this pice of code will work fine if you change your CustomTimePicker style in xml from clock to Analog . Although even i'm in need to find out which widget does time picker in clock style uses ? any idea anyone?Situated
Hi - how do I init this class on th UI - do i init a it using a timepicker component eg CustomTimePickerDialog ctp = ...findViewById(R.id.timePicker); ?Brede
This code works great, except there's one flaw. If updateTime() is called, the minutes are not normalized by dividing by TIME_PICKER_INTERVAL before setting the minutes value on the TimePicker.Circum
Also, the implementation of onClick() has changed in the most recent versions of the API to handle BUTTON_NEGATIVE. I'll update the answer to reflect these changes.Circum
This code also, inexplicably, doesn't work in 7.0 Nougat. The source code would seem it's mostly unchanged from 6.0.1 Marshmallow in terms of how it handles the TimePickerMode in the theme to choose between TimePickerSpinnerDelegate and TimePickerClockDelegate. But despite the mode being set to "spinner", on API 24 the clock layout is always used. This is an issue with the stock android.app.TimePickerDialog though.Circum
I created an issue in the Android bug tracker: code.google.com/p/android/issues/detail?id=222208Circum
I've written some workaround code for this issue with Nougat only displaying the clock. I can share if anyone else is experiencing the same problem.Circum
can any one help me how to call this class. bcz simply I am calling this constructor and calling method dialog.show(). But getting exception android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?Cardiology
I feel this will break in the future - Google is clamping down on accessing internals with reflection :(Cleary
team, I am getting this error, any help please. java.lang.NoSuchFieldException: TimePicker with Android 9 .Malacca
how can we achieve this in Clock Mode?Morton
beware that when retrieving the resulting time via an OnTimeChangedListener, the resulting "minute" var transmitted is INCORRECT, and will be equal to "minute selected / interval". for example, using an interval of 5 minutes, selecting 6:15 on the UI will yield an OnTimeChangedListener minute var of 3. 6:30 yields minute=6, etc.Prober
@RiddhiShah, this can be done in clock mode. Just omit the attribute TimePickerDialog.THEME_HOLO_LIGHT from the constructor and this makes the timepicker default to clock mode. your new call to super will be something like super(context, null, hourOfDay, minute / TIME_PICKER_INTERVAL, is24HourView);Howler
With compileSdkVersion 30 and Android 11, getting the minuteSpinner in onAttachedToWindow works differently: mTimePicker = findViewById(Resources.getSystem().getIdentifier("timePicker", "id", "android")), then val minuteSpinner = mTimePicker?.findViewById<NumberPicker>(Resources.getSystem().getIdentifier("minute", "id", "android")) (Kotlin)Gass
i have a problem when i make interval 30 For example if you change from 14:00 to :30, the hour goes back to 13.Smoothbore
M
18

There is this awesome library MaterialDateTimePicker that creates beautiful styled material timepickers.

You can use one of the following methods to define your interval:

  • setSelectableTimes(Timepoint[] times) You can pass in an array of Timepoints. These values are the only valid selections in the picker. setMinTime(Timepoint time) and setMaxTime(Timepoint time) will further trim this list down.

  • setTimeInterval(int hourInterval, int minuteInterval, int secondInterval) Set the interval for selectable times in the TimePickerDialog. This is a convenience wrapper around setSelectableTimes

Mccready answered 2/5, 2016 at 10:59 Comment(4)
does that lib work on a fragment with another views in it, or just as a dialog?Milepost
@JohnSardinha, it's a dialog based on the corresponding Android api, but needs an instance of the FragmentManager for it's show() function.Ninny
This library works for me. Solved my problem. I can set intervals of 30 minutes, for example.Bedew
can this lib be customized to use spinner instead of clock? Most solutions I have seen seem to use reflection and they do not work on all android versions.Murphy
C
11
/**
 * Set TimePicker interval by adding a custom minutes list
 *
 * @param timePicker
 */
private void setTimePickerInterval(TimePicker timePicker) {
    try {

        NumberPicker minutePicker = (NumberPicker) timePicker.findViewById(Resources.getSystem().getIdentifier(
                "minute", "id", "android"));
        minutePicker.setMinValue(0);
        minutePicker.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
    } catch (Exception e) {
        Log.e(TAG, "Exception: " + e);
    }
}
Candelabrum answered 13/10, 2017 at 11:53 Comment(0)
S
7

As @anddev84 said, you can do it with your own customized TimePickerDialog.

However, take a look of the source code you can find:

  1. TimePickerDialog is a frame layout, see this file. And it just contains a TimePicker
  2. The TimePicker widget is just a linear layout, see this file. And you can see the minute spinner is a NumberPicker
  3. Refer to the code of NumberPicker, you will find it has a public method setDisplayedValues(String[] displayedValues)

    /**
     * Sets the values to be displayed.
     *
     * @param displayedValues The displayed values.
     */
    public void setDisplayedValues(String[] displayedValues)
    

So, with these information, I suppose you can simply customize your own time picker dialog with limited minutes displayed.

Supportive answered 2/12, 2013 at 4:25 Comment(0)
U
2

Struggled with 30 min interval more then hour. Might struggle more if wouldn't see the comment of @Lee. So just post a full code of dialog with 30 min interval:

public class IntervalTimePickerDialog extends TimePickerDialog {
    private static final String TAG = "IntervalPickerDialog";

    private final static int TIME_PICKER_INTERVAL = 30;
    private TimePicker timePicker;
    private final OnTimeSetListener callback;

    private int lastHour = -1;
    private int lastMinute = -1;

    public IntervalTimePickerDialog(Context context, int themeId, OnTimeSetListener callBack,
                                    int hourOfDay, int minute, boolean is24HourView) {
        super(context, themeId, callBack, hourOfDay, minute / TIME_PICKER_INTERVAL,
                is24HourView);
        lastHour = hourOfDay;
        lastMinute = minute;
        this.callback = callBack;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (callback != null && timePicker != null) {
            timePicker.clearFocus();
            callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
                    timePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
        }
    }

    @Override
    protected void onStop() {
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            this.timePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
            mMinuteSpinner.setMinValue(0);
            mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
        super.onTimeChanged(view, hourOfDay, minute);
        if (lastHour != hourOfDay && lastMinute != minute) {
            view.setCurrentHour(lastHour);
            lastMinute = minute;
        } else {
            lastHour = hourOfDay;
            lastMinute = minute;
        }
    }
Utopianism answered 19/2, 2016 at 8:39 Comment(4)
can any one help me how to call this class. bcz simply I am calling this constructor and calling method dialog.show(). But getting exception android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?Cardiology
@ Yevhenii Kanivets , getting this error for Android 9 , any help please . java.lang.NoSuchFieldException: TimePickerMalacca
@Malacca they've just changed the name of field to smth another (don't know which is the new name). This is exactly why reflection is the bad solution.Utopianism
@Yevhenii Kanivets , thank you for your reply, so, do we have another solution to keep the spinner UI ?Malacca
K
1

Looking at the code for TimePickerDialog, it doesn't appear they give you a way to directly modify the TimePicker before it gets shown to the user and you see the "wrong minutes" are you show in the picture. See TimePickerDialog.java

My recommendation is to create your own TimePickerDialog, basing the design off the Android one. It might sound daunting at first, but

  1. that way you can customize the implementation however you want, including initializing the TimePicker values to display for the minutes (as mentioned here), and also
  2. it actually shouldn't be very hard, the Android TimePickerDialog.java itself is only 160 lines, very manageable.
Kallick answered 2/12, 2013 at 3:55 Comment(0)
S
1

I've made an addition to the excellent accepted answer above. The problem with it is that, in at least some versions of Android, when you change the selected time it will replace the dialog title with an incorrect time value. You can't override the offending method, updateTitle(), but you can intercept the call at onTimeChanged() and either not call super or call it with fixed arguments.

I keyed mine off of whether the setTitle() method had been called with a non-zero string ID, but you could just have a getter/setter for the boolean itself or whatever.

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
    if (autoTitle)
    {
        // Super will call a private updateTitle() method, so lets make
        // sure it has the right minute value.
        super.onTimeChanged(view, hourOfDay, minute * TIME_PICKER_INTERVAL);
    }
    else
    {
        // do nothing
    }
}

@Override
public void setTitle(int id)
{
    super.setTitle(id);
    autoTitle = (id == 0);
}

...

private boolean autoTitle = true;
Sabbatarian answered 17/2, 2016 at 2:43 Comment(0)
P
1

Solutions so far don't work with listeners and when setting time programmatically. This solutions is fully usable and stable. Also Kotlin...

import android.content.Context
import android.util.AttributeSet
import android.widget.NumberPicker
import android.widget.TimePicker
import androidx.databinding.BindingAdapter
import java.lang.reflect.Field
import java.util.*


class TimePickerInterval @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TimePicker(context, attrs, defStyleAttr) {

    private var MINUTE_INTERVAL = 1
    override fun getCurrentMinute(): Int {
        return super.getCurrentMinute() * MINUTE_INTERVAL
    }

    override fun getMinute(): Int {
        return super.getMinute() * MINUTE_INTERVAL
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        setUp()
    }

    private fun setUp() {
        try {
            val classForid = Class.forName("com.android.internal.R\$id")
            val field: Field = classForid.getField("minute")
            val mMinuteSpinner = findViewById<NumberPicker>(field.getInt(null))
            mMinuteSpinner.minValue = 0
            mMinuteSpinner.maxValue = 60 / MINUTE_INTERVAL - 1
            val displayedValues: MutableList<String> = ArrayList()
            var i = 0
            while (i < 60) {
                displayedValues.add(String.format("%02d", i))
                i += MINUTE_INTERVAL
            }
            mMinuteSpinner.displayedValues = displayedValues.toTypedArray()

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

    override fun setOnTimeChangedListener(onTimeChangedListener: OnTimeChangedListener) {
        super.setOnTimeChangedListener { tp, hour, minute ->
            onTimeChangedListener.onTimeChanged(tp, hour, minute * MINUTE_INTERVAL)
        }
    }

    override fun setMinute(minute: Int) {
        super.setMinute(minute/MINUTE_INTERVAL)
    }

    companion object {
        @JvmStatic
        @BindingAdapter("time_picker_set_minute_interval")
        fun setInterval(view: TimePickerInterval, interval: Int?) {
            interval?.let {
                view.MINUTE_INTERVAL = interval
                view.setUp()
            }
        }
    }
}

In your XML:

        <your.path.TimePickerInterval
            android:id="@+id/tp_to"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:timePickerMode="spinner"
            time_picker_set_minute_interval="@{5}"
 />
Poesy answered 8/9, 2021 at 15:34 Comment(0)
M
0

The answer above works really fine for older version of Android, but it didn't work for me in Android 7 Nougat, basically the date picker is changed completely to use the Clock mode... I kind of merge the code proposed here with https://gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f, then it set by default the mode of the TimePickerDialog to show the Spinner controls, and it runs the code to show only 15minuts intervals in my case.

The code is posted here https://gist.github.com/smaugho/14dae83f3284fa05455ee0a9e4f13099

public class CustomTimePickerDialog extends TimePickerDialog {

private final static int TIME_PICKER_INTERVAL = 15;
private TimePicker timePicker;
private final OnTimeSetListener callback;

  public HorekoTimePicker(Context context,
        OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
      super(context, callBack, hourOfDay, minute/TIME_PICKER_INTERVAL, is24HourView);
      this.callback = callBack;
    fixSpinner(context, hourOfDay, minute, is24HourView);
  }

/**
 * Workaround for this bug: https://code.google.com/p/android/issues/detail?id=222208
 * In Android 7.0 Nougat, spinner mode for the TimePicker in TimePickerDialog is
 * incorrectly displayed as clock, even when the theme specifies otherwise, such as:
 *
 *  <resources>
 *      <style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
 *          <item name="android:timePickerStyle">@style/Widget.MyApp.TimePicker</item>
 *      </style>
 *
 *      <style name="Widget.MyApp.TimePicker" parent="android:Widget.Material.TimePicker">
 *          <item name="android:timePickerMode">spinner</item>
 *      </style>
 *  </resources>
 *
 * May also pass TimePickerDialog.THEME_HOLO_LIGHT as an argument to the constructor,
 * as this theme has the TimePickerMode set to spinner.
 *
 * Taken from: https://gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f
 */
private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // android:timePickerMode spinner and clock began in Lollipop
        try {

            // Get the theme's android:timePickerMode
            final int MODE_SPINNER = 1;
            Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
            Field timePickerStyleableField = styleableClass.getField("TimePicker");
            int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null);
            final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0);
            Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode");
            int timePickerModeStyleable = timePickerModeStyleableField.getInt(null);
            final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER);
            a.recycle();

            if (mode == MODE_SPINNER) {

                timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this);
                Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate");
                Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate");
                Object delegate = delegateField.get(timePicker);
                Class<?> spinnerDelegateClass;
                if (Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP) {
                    spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate");
                } else {
                    // TimePickerSpinnerDelegate was initially misnamed TimePickerClockDelegate in API 21!
                    spinnerDelegateClass = Class.forName("android.widget.TimePickerClockDelegate");
                }

                // In 7.0 Nougat for some reason the timePickerMode is ignored and the delegate is TimePickerClockDelegate
                if (delegate.getClass() != spinnerDelegateClass) {
                    delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate!
                    timePicker.removeAllViews(); // remove the TimePickerClockDelegate views
                    Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class);
                    spinnerDelegateConstructor.setAccessible(true);
                    // Instantiate a TimePickerSpinnerDelegate
                    delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0);
                    delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate
                    // Set up the TimePicker again, with the TimePickerSpinnerDelegate
                    timePicker.setIs24HourView(is24HourView);
                    timePicker.setCurrentHour(hourOfDay);
                    timePicker.setCurrentMinute(minute);
                    timePicker.setOnTimeChangedListener(this);
                }

                setTimeIntervals();
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

private static Field findField(Class objectClass, Class fieldClass, String expectedName) {
    try {
        Field field = objectClass.getDeclaredField(expectedName);
        field.setAccessible(true);
        return field;
    } catch (NoSuchFieldException e) {} // ignore
    // search for it if it wasn't found under the expected ivar name
    for (Field searchField : objectClass.getDeclaredFields()) {
        if (searchField.getType() == fieldClass) {
            searchField.setAccessible(true);
            return searchField;
        }
    }
    return null;
}

  @Override
protected void onStop() { }

/*
 * Feature #363: (Un)availability times in 15min interval
 * https://abix.webhop.net/redmine/issues/363
 * Solution extracted from
 * https://mcmap.net/q/328990/-show-timepicker-with-minutes-intervals-in-android
 */

@Override
public void onClick(DialogInterface dialog, int which) {
    super.onClick(dialog, which);

    if (callback != null && timePicker != null) {
        timePicker.clearFocus();
        callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
            timePicker.getCurrentMinute()*TIME_PICKER_INTERVAL);
    }
}

private void setTimeIntervals() {
    try {
        Class<?> classForid = Class.forName("com.android.internal.R$id");
        Field field = classForid.getField("minute");

        NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
        mMinuteSpinner.setMinValue(0);
        mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));

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

}

}

Microparasite answered 7/7, 2017 at 14:43 Comment(2)
@ Adrián Rivero : java.lang.NoSuchFieldException: TimePicker with Android 9 . I am getting this error, any help please.Malacca
@Malacca try removing the line ` throw new RuntimeException(e);` from catch block this will workCatchascatchcan
C
-1

If you wont to use the same time picker (not clock) dialog in android 5+ just change the theme. You can change directly in the constructor:

 public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int time_interval) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, callBack, hourOfDay, minute / time_interval, is24HourView);
        this.TIME_PICKER_INTERVAL = time_interval;
        this.callback = callBack;
    }
Crap answered 2/9, 2015 at 16:42 Comment(0)
F
-2

Based on Tanmay Mandal's answer shown above, I have implemented a solution for the TimePicker Widget (not the TimePickerDialog). The trick here is to substitute the original TimePicker element in the layout of the activity for a LinearLayout element, in order to add our custom TimePicker programmatically. See example below:

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.widget.NumberPicker;
import android.widget.TimePicker;

public class MyTimePicker extends TimePicker {

  private static final int TIME_PICKER_INTERVAL = 5;

    public MyTimePicker(Context context) {
        super(context);
    }

    @Override
    public Integer getCurrentMinute() {
        return super.getCurrentMinute()*TIME_PICKER_INTERVAL;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field field = classForid.getField("minute");

            NumberPicker mMinuteSpinner = (NumberPicker) findViewById(field.getInt(null));
            mMinuteSpinner.setMinValue(0);
            mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<String>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL)
                displayedValues.add(String.format("%02d", i));
             mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));     
        } catch (Exception e) {
        e.printStackTrace();
    }

   }

}

And for our activity:

          @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

            LinearLayout ll = (LinearLayout) findViewById(R.id.myLinearLayout);
            ll.removeAllViews();
            MyTimePicker tp = new MyTimePicker(this);
            tp.setIs24HourView(true);
            Calendar cal = Calendar.getInstance(); // Current time
        tp.setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
            tp.setCurrentMinute(cal.get(Calendar.MINUTE)/5); // Aprox current minute
            ll.addView(tp);

}
Frants answered 29/12, 2014 at 19:19 Comment(4)
Your TimePicker class have error: NumberPicker mMinuteSpinner = (NumberPicker) mMinuteSpinner.setMinValue(0);Crap
Ups, you are right. I forgot a code line. Bug solved now. Thanks!Frants
How does this get attached to the UI, do i need a Time picker on in my xml layout?Brede
You don't need any TimePicker in your xml layout. Just place a LinearLayout element at the position the TimePicker would be and let the Activity populate it as shown above.Frants

© 2022 - 2025 — McMap. All rights reserved.