wdullaer/MaterialDateTimePicker
Pick a date or time on Android in style
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓10 active contributors
- ✓Apache-2.0 licensed
- ✓CI configured
Show all 6 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 4y ago
- ⚠Single-maintainer risk — top contributor 80% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/wdullaer/materialdatetimepicker)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/wdullaer/materialdatetimepicker on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: wdullaer/MaterialDateTimePicker
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/wdullaer/MaterialDateTimePicker shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 10 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 4y ago
- ⚠ Single-maintainer risk — top contributor 80% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live wdullaer/MaterialDateTimePicker
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/wdullaer/MaterialDateTimePicker.
What it runs against: a local clone of wdullaer/MaterialDateTimePicker — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in wdullaer/MaterialDateTimePicker | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1384 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of wdullaer/MaterialDateTimePicker. If you don't
# have one yet, run these first:
#
# git clone https://github.com/wdullaer/MaterialDateTimePicker.git
# cd MaterialDateTimePicker
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of wdullaer/MaterialDateTimePicker and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "wdullaer/MaterialDateTimePicker(\\.git)?\\b" \\
&& ok "origin remote is wdullaer/MaterialDateTimePicker" \\
|| miss "origin remote is not wdullaer/MaterialDateTimePicker (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java" \\
&& ok "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java" \\
|| miss "missing critical file: library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java"
test -f "library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java" \\
&& ok "library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java" \\
|| miss "missing critical file: library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java"
test -f "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java" \\
&& ok "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java" \\
|| miss "missing critical file: library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java"
test -f "library/src/main/java/com/wdullaer/materialdatetimepicker/time/RadialPickerLayout.java" \\
&& ok "library/src/main/java/com/wdullaer/materialdatetimepicker/time/RadialPickerLayout.java" \\
|| miss "missing critical file: library/src/main/java/com/wdullaer/materialdatetimepicker/time/RadialPickerLayout.java"
test -f "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DateRangeLimiter.java" \\
&& ok "library/src/main/java/com/wdullaer/materialdatetimepicker/date/DateRangeLimiter.java" \\
|| miss "missing critical file: library/src/main/java/com/wdullaer/materialdatetimepicker/date/DateRangeLimiter.java"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1384 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1354d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/wdullaer/MaterialDateTimePicker"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
MaterialDateTimePicker is an Android library that provides Material Design-compliant date and time picker dialogs matching Google's design specification. It replaces the native Android pickers with stylized alternatives that support date range limiting, custom theming, and accessibility features, available as a Gradle dependency for Android 4.1+. Single-module Gradle library structure: library/src/main/java contains core pickers split into date/ and time/ packages. DatePickerDialog, TimePickerDialog, and supporting views (MonthView, YearPickerView, AmPmCirclesView) handle UI rendering. library/src/androidTest/ contains instrumented tests. DateRangeLimiter and related interfaces enable customization without modifying core code.
👥Who it's for
Android app developers who need to collect dates and times from users and want Material Design compliance without building custom pickers. Primarily used in production apps that require accessible, themable date/time input following Google's Material Design guidelines.
🌱Maturity & risk
Production-ready and actively maintained. The library has reached version 4.2.3 on Maven Central, includes comprehensive test coverage (DefaultDateRangeLimiterTest, DefaultTimepointLimiterTest, TimepointTest in androidTest/), and uses CI via Travis CI (.travis.yml). However, recent commit activity is not visible in the provided metadata—check GitHub for current maintenance status.
Low risk for production use. Single-maintainer risk exists (wdullaer owns the repo), and Java 8 language features require transpilation configuration (compileOptions in build.gradle). No dependency bloat visible—the core is self-contained without external picker libraries. Main risk is Android version deprecation support (dropped Android 4.0 in 3.6.4), so verify your minSdkVersion compatibility.
Active areas of work
No specific recent activity visible in provided metadata. Check the GitHub issues and pull requests page for current work; the Gitter chat badge suggests active community discussion.
🚀Get running
Clone the repo, then build the library module: git clone https://github.com/wdullaer/MaterialDateTimePicker.git && cd MaterialDateTimePicker && ./gradlew build. Gradle wrapper is included (gradle/wrapper/gradle-wrapper.jar). To use in your app, add implementation 'com.wdullaer:materialdatetimepicker:4.2.3' to your app's build.gradle, and ensure Java 8 transpilation is enabled in compileOptions.
Daily commands:
For library development: ./gradlew build compiles and runs androidTest. For testing in an app: create a DatePickerDialog or TimePickerDialog fragment, implement OnDateSetListener/OnTimeSetListener callbacks, and show the dialog. See README.md for code examples (referenced in snippet but full usage code not in metadata).
🗺️Map of the codebase
library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java— Entry point for date picker functionality; implements the core DialogFragment that orchestrates date selection UI and validation logic.library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java— Entry point for time picker functionality; implements the core DialogFragment for radial time selection and AM/PM handling.library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java— Core calendar month view rendering; manages day grid layout, selection state, and date range constraints.library/src/main/java/com/wdullaer/materialdatetimepicker/time/RadialPickerLayout.java— Core radial time selector UI component; handles gesture input, hour/minute/second selection via circular layout.library/src/main/java/com/wdullaer/materialdatetimepicker/date/DateRangeLimiter.java— Interface defining date validation and constraint rules; crucial abstraction for enforcing min/max dates and disabled date patterns.library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimepointLimiter.java— Interface defining time validation and constraint rules; enforces available time selections and minute/second intervals.
🛠️How to make changes
Add custom date range constraints
- Implement the DateRangeLimiter interface by extending DefaultDateRangeLimiter or creating a custom class with your validation logic (
library/src/main/java/com/wdullaer/materialdatetimepicker/date/DefaultDateRangeLimiter.java) - Call setDateRangeLimiter() on DatePickerDialog instance to inject your custom limiter (
library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java) - Your limiter's isOutOfRange() and getDisabledDays() methods will be called by DayPickerView to control day availability (
library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java)
Add custom time constraints and intervals
- Implement TimepointLimiter interface by extending DefaultTimepointLimiter with your custom time validation (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/DefaultTimepointLimiter.java) - Call setTimepointLimiter() on TimePickerDialog to register your custom limiter (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java) - RadialPickerLayout will call your limiter's isOutOfRange() to validate selected times and enforce minute/second intervals (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/RadialPickerLayout.java)
Customize the date picker theme colors
- Create theme colors in your app's colors.xml by overriding Material DateTime Picker color resources (mdtp_accent_color, mdtp_primary_color, etc.) (
library/src/main/res/color/mdtp_date_picker_selector.xml) - Pass your theme context to DatePickerDialog.newInstance() and the picker will use your app's color scheme (
library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java) - MonthView and RadialSelectorView read theme colors from context resources during rendering (
library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthView.java)
Add a new custom Timepoint model or extend Timepoint validation
- Examine the Timepoint class structure to understand hour/minute/second/AM-PM representation (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/Timepoint.java) - Extend DefaultTimepointLimiter and override isOutOfRange() to add custom validation logic (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/DefaultTimepointLimiter.java) - Call setTimepointLimiter() on TimePickerDialog with your enhanced limiter instance (
library/src/main/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialog.java)
🪤Traps & gotchas
Java 8 language features require explicit compileOptions configuration in consuming app (sourceCompatibility JavaVersion.VERSION_1_8, targetCompatibility JavaVersion.VERSION_1_8)—omitting this causes compilation errors even if min SDK is ≥21. DatePickerDialog and TimePickerDialog must be shown via FragmentManager (DialogFragment pattern)—directly instantiating and adding won't work. Callbacks (OnDateSetListener, OnTimeSetListener) must be implemented by hosting Activity/Fragment—dialogs don't work standalone. Accessibility features depend on correct AndroidManifest.xml configuration in library/src/main/AndroidManifest.xml—check for required permissions.
🏗️Architecture
💡Concepts to learn
- DialogFragment lifecycle and callbacks — DatePickerDialog and TimePickerDialog extend DialogFragment—understanding Fragment lifecycle, show(), and callback patterns is essential for correctly displaying pickers in activities
- Material Design picker patterns — This library implements specific Material Design specifications for date/time selection (year→month→day flow, AM/PM selection)—understanding the spec helps predict UI behavior
- RecyclerView adapters and ViewHolder pattern — MonthAdapter and SimpleMonthAdapter use RecyclerView.Adapter pattern for efficient month grid rendering—used when navigating dates
- Android theme attributes and style inheritance — Theming the pickers requires understanding Android theme attribute resolution—customization happens via theme attrs, not direct color parameters
- Java 8 Stream API and lambda expressions — Library uses Java 8 features (lambdas, streams)—consuming apps must enable Java 8 transpilation, and contributors must write Java 8-compatible code
- Android Accessibility (ContentDescription, AccessibilityDelegate) — AccessibleLinearLayout, AccessibleTextView, and AccessibleDateAnimator ensure screen reader compatibility—critical for a11y compliance in date/time apps
- Calendar API and timezone handling — DateRangeLimiter and DefaultDateRangeLimiter work with java.util.Calendar—understanding Calendar's month indexing (0-based) and timezone implications prevents date off-by-one errors
🔗Related repos
code-path/android-datepicker— Alternative Android date picker library with similar Material Design goals but different UI approachgoogle/android-platform-frameworks— MaterialDateTimePicker uses code from Android framework's datetimepicker as base (acknowledged in README)—original source for picker logicmaterial-components/material-components-android— Google's official Material Design components for Android—includes date/time pickers and theming utilities used in modern appswdullaer/MaterialNumberPicker— Same author's complementary library for Material Design number selection—often paired with MaterialDateTimePicker in formsandroidx/androidx— AndroidX (successor to Android support libraries) contains modern DatePicker and TimePicker implementations as alternatives
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive instrumented tests for DatePickerDialog and TimePickerDialog
The library has minimal androidTest coverage (only 3 test files for utilities). The core dialog classes DatePickerDialog.java and TimePickerDialog.java lack instrumented tests to verify UI interactions, state management, and date/time selection flows. This is critical for a UI-focused library where visual correctness and user interaction matter.
- [ ] Create library/src/androidTest/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialogTest.java with tests for dialog initialization, date selection, and callbacks
- [ ] Create library/src/androidTest/java/com/wdullaer/materialdatetimepicker/time/TimePickerDialogTest.java with tests for time selection, AM/PM toggling, and state persistence
- [ ] Add tests for MonthView.java, YearPickerView.java, and RadialPickerLayout.java to verify calendar/time rendering and touch interactions
Migrate from jcenter() to Maven Central in build configuration and update Gradle wrapper
The build.gradle and library/build.gradle still reference jcenter() which was sunset by JFrog in 2021. Additionally, the Gradle wrapper is pinned to 3.6.3 (from 2020), creating potential security and compatibility issues. This modernization would improve build reliability and align with current Android development practices.
- [ ] Update build.gradle and library/build.gradle to remove jcenter() repository reference, keeping only google() and Maven Central
- [ ] Update gradle/wrapper/gradle-wrapper.properties to use a recent stable Gradle version (7.x or 8.x)
- [ ] Test build with updated Gradle to ensure compatibility and verify library still publishes to Maven Central correctly
Add GitHub Actions CI workflow to replace Travis CI and test against multiple Android API levels
The repo uses .travis.yml for CI (Travis CI is largely deprecated), and there's no verification that the library works across the stated Android 4.1+ support range. A GitHub Actions workflow would test against multiple Android API levels (21, 26, 31, 33+) to catch regressions and ensure broad compatibility.
- [ ] Create .github/workflows/android-build.yml to run gradle build and instrumented tests on Android API 21, 26, 31, and 33
- [ ] Add lint checks to the workflow to catch code quality issues in library/src/main/java
- [ ] Update README.md to show GitHub Actions badge instead of Travis CI badge
🌿Good first issues
- Add unit tests for VerticalTextView.java and GravitySnapHelper.java—no test files exist for these utility classes in androidTest/, making them good targets for test-first contributions
- Document the custom DateRangeLimiter interface with Javadoc and example code snippet in README_ES.md / README.md—currently no usage examples visible for extending DefaultDateRangeLimiter
- Add accessibility labels to SimpleDayPickerView.java and YearPickerView.java—TextViewWithCircularIndicator and AccessibleDateAnimator exist but no clear a11y testing in androidTest/
⭐Top contributors
Click to expand
Top contributors
- @wdullaer — 80 commits
- [@Lauri Aalto](https://github.com/Lauri Aalto) — 7 commits
- @SaeedZhiany — 4 commits
- @dependabot-preview[bot] — 2 commits
- @hearsilent — 2 commits
📝Recent commits
Click to expand
Recent commits
f849a5c— Merge pull request #667 from wdullaer/dependabot/gradle/com.pholser-junit-quickcheck-core-0.9.2 (wdullaer)65ce087— Bump junit-quickcheck-core from 0.9.1 to 0.9.2 (dependabot-preview[bot])9640227— Merge pull request #664 from wdullaer/dependabot/gradle/com.squareup.leakcanary-leakcanary-android-2.3 (wdullaer)941b472— Bump leakcanary-android from 2.2 to 2.3 (dependabot-preview[bot])3b32596— fix(rtl-layout): Mirror arrow buttons in rtl layout (wdullaer)8fb53c2— chore(deps): Upgrade dependencies (wdullaer)2894503— Merge pull request #650 from putrabangga/fixingTimeLimiter (wdullaer)183e5fb— fixed time limiter on lower upper time (putrabangga)e3907c0— Create FUNDING.yml (wdullaer)de5ee5c— Add an example showing how to change the default selection (wdullaer)
🔒Security observations
The MaterialDateTimePicker library has moderate security concerns primarily related to outdated build tools and deprecated dependency repositories. The most critical issue is the use of JCenter (sunset in 2021) and Gradle 3.6.3 (released 2020), both of which lack security updates. The codebase itself appears to be a UI library focused on date/time picking with low inherent injection risk, but the build infrastructure needs modernization. No hardcoded secrets or obvious code vulnerabilities were detected in the visible file structure. Immediate action should be taken to update the Gradle plugin version and migrate away from JCenter to maintain security patch availability for transitive dependencies.
- High · Outdated Gradle Build Tool —
build.gradle (classpath 'com.android.tools.build:gradle:3.6.3'). The project uses Gradle 3.6.3 which was released in 2020 and is significantly outdated. This version may contain known security vulnerabilities in the Android build system and lacks security patches for dependency resolution issues. Fix: Update to the latest stable version of the Android Gradle Plugin (currently 8.x). This will include important security fixes and improved dependency verification. - High · Use of Deprecated JCenter Repository —
build.gradle (jcenter() in repositories). The project configures JCenter as a repository, which was sunset by JFrog in 2021. This means dependencies may not be properly maintained and security updates could be missed. Additionally, JCenter no longer receives updates for many packages. Fix: Remove jcenter() and rely exclusively on Google Maven Repository and Maven Central. Update all repositories to use only actively maintained sources: google() and mavenCentral(). - Medium · Missing Dependency Version Pinning —
library/build.gradle (not fully visible in provided content). The build.gradle file does not show explicit versions for project dependencies (only build tool). This could lead to unexpected behavior if transitive dependencies update to incompatible or vulnerable versions without explicit control. Fix: Use explicit version constraints for all dependencies. Consider using dependency lock files or constraint declarations to ensure reproducible builds and prevent transitive dependency vulnerabilities. - Medium · Missing Security Configuration in Android Manifest —
library/src/main/AndroidManifest.xml. Based on the file structure showing AndroidManifest.xml, without visibility into its contents, there may be missing security configurations such as missing android:usesCleartextTraffic or network security configuration. Fix: Ensure the manifest includes: android:usesCleartextTraffic='false' and references a network_security_config.xml that restricts to HTTPS only and validates certificates properly. - Low · Build System Lacks Security Scanning —
build.gradle. The gradle configuration does not show evidence of dependency scanning tools like OWASP Dependency Check or Gradle's built-in vulnerability scanning being configured in the build pipeline. Fix: Integrate security scanning into the build process by adding plugins like: id 'org.owasp.dependencycheck' version '8.x' or enable Gradle's native vulnerability detection with gradle build --scan. - Low · No Evidence of Proguard/R8 Configuration for Release Builds —
library/build.gradle. The provided build.gradle excerpt does not show proguard or R8 configuration, which is important for obfuscating code and reducing attack surface in release builds. Fix: Ensure release builds use R8/Proguard with obfuscation enabled. Add minifyEnabled true and appropriate proguard-rules.pro configuration to prevent reverse engineering of sensitive logic.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.