# MaterialDateTimePicker follows the framework picker API, down to the accent color precedence

> An Android library that repackages the framework datetime picker code to look like the Material Design spec, with themable dialogs and two layout versions. The integration is a one line Gradle dependency plus a Java 8 stanza, and the newest tagged release is 4.2.3 from 2019.

**wdullaer/MaterialDateTimePicker** — GitHub describes it as Pick a date or time on Android in style. The repository metadata lists Java as its primary language. The metadata lists the Apache-2.0 license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/wdullaer/MaterialDateTimePicker
- Stars: 4,621 · Forks: 926
- Language: Java
- License: Apache-2.0
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/wdullaer-materialdatetimepicker

## Three steps, and the factory method does the wiring

The API deliberately mirrors the pickers already in the Android framework, so the learning curve is short for anyone who has used the platform dialogs. There are three steps: implement OnTimeSetListener or OnDateSetListener, create a TimePickerDialog or DatePickerDialog through the supplied factory, and theme the result. The callbacks look like this:

```java
@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
  String time = "You picked the following time: "+hourOfDay+"h"+minute+"m"+second;
  timeTextView.setText(time);
}
```

Typically the Activity or Fragment that creates the picker is what implements the listener. The dialog is then built with newInstance(), given its default values, and shown:

```java
Calendar now = Calendar.getInstance();
DatePickerDialog dpd = DatePickerDialog.newInstance(
  MainActivity.this,
  now.get(Calendar.YEAR), // Initial year selection
  now.get(Calendar.MONTH), // Initial month selection
  now.get(Calendar.DAY_OF_MONTH) // Inital day selection
);
// If you're calling this from a support Fragment
dpd.show(getFragmentManager(), "Datepickerdialog");
// If you're calling this from an AppCompatActivity
// dpd.show(getSupportFragmentManager(), "Datepickerdialog");
```

The commented line matters more than it looks. A support Fragment and an AppCompatActivity hand you different fragment managers, and picking the wrong one is the first failure you will hit.

## Version 2 is the default, version 1 is the older kitkat layout

Each picker ships in two layout versions, and they are not cosmetic variations of one design. Version 1 is the original layout, based on what the design kit used in the kitkat and early Material era. Version 2 follows the guidelines published when Android Marshmallow launched, and it is both the default and, in the project's words, still the most current design.

You only need to touch this when your design predates that default:

```java
dpd.setVersion(DatePickerDialog.Version.VERSION_2);
```

The reason to know both versions exist is upgrade planning. Screens designed years ago against version 1 can change appearance on a library update without any code change from you, because the default flipped. If your design system has an explicit opinion about the picker, set the version explicitly in code and treat the change as deliberate rather than inherited.

That is the general shape of this library's API, by the way. Where the platform has two plausible answers, the library usually exposes a switch rather than choosing for you permanently.

## Accent color resolution is a four step precedence list

The pickers theme themselves from the current theme at the moment they are created, and the README spells out the exact order in which a color wins. First is setAccentColor(int color) called in your own code. Second is android.R.attr.colorAccent, on Android 5.0 and later. Third is R.attr.colorAccent, which is what you get when using AppCompat. Fourth, and only if none of the others are set in your project, are the library's own R.color.mdtp_accent_color and R.color.mdtp_accent_color_dark.

That last step is the override route, and it exists so a project can change the library's colors without touching dialog code:

```xml
<color name="mdtp_accent_color">#009688</color>
<color name="mdtp_accent_color_dark">#00796b</color>
```

The practical consequence for debugging is that a picker can ignore your color for a reason you did not intend. An explicit setAccentColor call outranks the theme, so a dialog that looks wrong in one screen and right in another is often a per call difference rather than a theme problem. The String overload parses through Color.parseColor(), while the int overload wants a ColorInt bytestring and forces the color fully opaque, which matters if you were expecting translucency to survive.

## Code flips dark theme, XML sets it, and code overwrites XML

Dark mode is a single attribute in your theme:

```xml
<item name="mdtp_theme_dark">true</item>
```

or a call on the dialog:

```java
dialog.setThemeDark(true);
```

The precedence is stated without ambiguity: the function calls overwrite the XML setting. So a theme that declares mdtp_theme_dark is a default, not a guarantee, and any code path that calls setThemeDark overrides it for that dialog. If a screen needs to look different from the rest of the app, the setThemeDark route is the supported way to do it, and you should expect to call it on every dialog you create rather than once at startup.

Similar per dialog setters cover the button labels. setOkColor() and setCancelColor() change the text color of the OK and Cancel buttons and behave like the accent setter, while setOkText() and setCancelText() replace the labels themselves and accept either a string or a string resource id, and work in both the date and the time dialog.

## The Java 8 stanza is not optional

The library uses Java 8 language features, and Android Studio has to transpile them, which means your build file needs a specific block:

```groovy
android {
  ...
  // Configure only for each module that uses Java 8
  // language features (either in its source code or
  // through dependencies).
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
```

The inline comment sets the scope for you: configure it only for each module that uses Java 8 features, whether those features come from your own source or from a dependency. This library is such a dependency, so every module that includes a picker needs it. Getting this wrong produces a build that fails to compile rather than one that runs badly, which is the friendlier failure mode, but it is a failure in the module you least expect if the picker sits in a shared library.

Two installation routes are offered and they suit different situations. The easy one is a single Gradle dependency:

```groovy
dependencies {
    implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
}
```

The other is adding the project as an Android Library directly, with all library files living in the library folder. That route suits apps that want to change the code rather than depend on a published artifact.

## setTitle means two different things in the two dialogs

The same method name behaves differently depending on which dialog receives it, and this is the easiest detail to get wrong. On a TimePickerDialog, setTitle(String) shows a title at the top of the dialog. On a DatePickerDialog, setTitle(String) shows a title at the top of the dialog instead of the day of the week.

So calling setTitle on a date picker does not add a header, it replaces the weekday line. If a design calls for both, this API will not give you both from a single call, and a developer who assumed the time picker behavior will find the weekday gone with nothing occupying its place. Read the per dialog list rather than assuming symmetry: the options are tagged [All] for the ones that work everywhere, and separately tagged for TimePickerDialog or DatePickerDialog when they do not.

The date dialog also owns the range restriction methods, setMinDate(Calendar day) and setMaxDate(Calendar day). Values before the minimum or after the maximum are deactivated rather than rejected after the fact, so an out of range tap gives the user a disabled day instead of an error message, which is the friendlier pattern for a picker but means you still need your own validation if the date can arrive from outside the dialog.

## No release since 2019, and the branch has been quiet since 2022

The maintenance picture is the first thing to establish. The most recent tags are 4.2.1 from 2019-06-05, 4.2.2 from 2019-08-18 and 4.2.3 from 2019-08-30, and the version referenced in the build file example is that same 4.2.3. The default branch last received a push on 2022-08-23. The repository is not archived, but there is no release newer than 2019 and no commit newer than 2022.

That gap is the reason to test before you adopt. An Android library that has not been rebuilt since 2022 predates several platform changes, and whether 4.2.3 compiles and behaves correctly against your current compileSdk is the question to answer in your own project rather than from the README. The repository is otherwise complete for a library of its age: a library folder with the sources, a sample app with its own build.gradle and ProGuard rules, gradlew and gradlew.bat wrappers, a licenses folder, a .travis.yml from the era when that was the CI standard, and README_ES.md alongside supported_languages.txt at the root.

Given that the platform now ships its own Material styled pickers, the honest comparison is against using those instead of adding a dependency that stopped moving seven years ago.

## Conclusion

Use MaterialDateTimePicker when you want the Material look for date and time entry in an existing Android app and can live with the framework callback shape, since the listeners match what the platform already uses. Verify two things before committing: that 4.2.3, the most recent tag, compiles against your current SDK level, and which layout version your design calls for, since version 1 is the older Marshmallow era look. If your app already targets a Material 3 picker from the platform itself, adding a library whose last commit is from 2022 is a step backwards.

## FAQ

### How do I add MaterialDateTimePicker to an Android project?

Add implementation 'com.wdullaer:materialdatetimepicker:4.2.3' to the dependencies block of your build.gradle, or add the project as an Android Library since all library files live in the library folder. Because the library uses Java 8 features, the module also needs compileOptions with sourceCompatibility and targetCompatibility set to JavaVersion.VERSION_1_8.

### Which Android versions does MaterialDateTimePicker support?

Android 4.1 and up. Android 4.0 was supported until version 3.6.4, so the floor moved when that release shipped.

### How does the accent color get chosen for the pickers?

The documented order is setAccentColor(int) in your code first, then android.R.attr.colorAccent on Android 5.0 and later, then R.attr.colorAccent as used with AppCompat, and only if none of those are set do the library's own mdtp_accent_color and mdtp_accent_color_dark resources apply.

### How do I restrict which dates a user can select?

DatePickerDialog provides setMinDate(Calendar) and setMaxDate(Calendar). Dates earlier than the minimum or later than the maximum are deactivated in the picker rather than rejected afterwards, so you validate separately if a date can arrive from another path.

## Sources

- [Official README](https://github.com/wdullaer/MaterialDateTimePicker#readme)
- [Project repository](https://github.com/wdullaer/MaterialDateTimePicker)
- [Release notes](https://github.com/wdullaer/MaterialDateTimePicker/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wdullaer-materialdatetimepicker
