Step 1. Add the JitPack repository to your build file
Add it in your root settings.gradle at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Add it in your settings.gradle.kts at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
Add to pom.xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add it in your project.clj at the end of repositories:
:repositories [["jitpack" "https://jitpack.io"]]
Step 2. Add the dependency
dependencies {
implementation 'com.github.huntj88:MaterialDateTimePicker:v3.2.2'
}
dependencies {
implementation("com.github.huntj88:MaterialDateTimePicker:v3.2.2")
}
<dependency>
<groupId>com.github.huntj88</groupId>
<artifactId>MaterialDateTimePicker</artifactId>
<version>v3.2.2</version>
</dependency>
libraryDependencies += "com.github.huntj88" % "MaterialDateTimePicker" % "v3.2.2"
:dependencies [[com.github.huntj88/MaterialDateTimePicker "v3.2.2"]]
Material DateTime Picker tries to offer you the date and time pickers as shown in the Material Design spec, with an easy themable API. The library uses the code from the Android frameworks as a base and tweaked it to be as close as possible to Material Design example.
Support for Android 4.0 and up.
Feel free to fork or issue pull requests on github. Issues can be reported on the github issue tracker.
Version 2 Layout
Date Picker | Time Picker
--- | ---
|
Version 1 Layout
Date Picker | Time Picker
---- | ----
|
The easiest way to add the Material DateTime Picker library to your project is by adding it as a dependency to your build.gradle
dependencies {
compile 'com.wdullaer:materialdatetimepicker:3.2.2'
}
You may also add the library as an Android Library to your project. All the library files live in library
.
The library follows the same API as other pickers in the Android framework. For a basic implementation, you'll need to
OnTimeSetListener
/OnDateSetListener
TimePickerDialog
/DatePickerDialog
using the supplied factoryOnTimeSetListener
/OnDateSetListener
In order to receive the date or time set in the picker, you will need to implement the OnTimeSetListener
or
OnDateSetListener
interfaces. Typically this will be the Activity
or Fragment
that creates the Pickers. The callbacks use the same API as the standard Android pickers.
@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);
}
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
String date = "You picked the following date: "+dayOfMonth+"/"+(monthOfYear+1)+"/"+year;
dateTextView.setText(date);
}
TimePickerDialog
/DatePickerDialog
using the supplied factoryYou will need to create a new instance of TimePickerDialog
or DatePickerDialog
using the static newInstance()
method, supplying proper default values and a callback. Once the dialogs are configured, you can call show()
.
Calendar now = Calendar.getInstance();
DatePickerDialog dpd = DatePickerDialog.newInstance(
MainActivity.this,
now.get(Calendar.YEAR),
now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH)
);
dpd.show(getFragmentManager(), "Datepickerdialog");
The library contains 2 layout versions for each picker.
You can set the layout version using the factory
dpd.setVersion(DatePickerDialog.Version.VERSION_2);
The pickers will be themed automatically based on the current theme where they are created, based on the current colorAccent
. You can also theme the dialogs via the setAccentColor(int color)
method. Alternatively, you can theme the pickers by overwriting the color resources mdtp_accent_color
and mdtp_accent_color_dark
in your project.
<color name="mdtp_accent_color">#009688</color>
<color name="mdtp_accent_color_dark">#00796b</color>
The exact order in which colors are selected is as follows:
setAccentColor(int color)
in java codeandroid.R.attr.colorAccent
(if android 5.0+)R.attr.colorAccent
(eg. when using AppCompat)R.color.mdtp_accent_color
and R.color.mdtp_accent_color_dark
if none of the others are set in your projectThe pickers also have a dark theme. This can be specified globablly using the mdtp_theme_dark
attribute in your theme or the setThemeDark(boolean themeDark)
functions. The function calls overwrite the XML setting.
<item name="mdtp_theme_dark">true</item>
TimePickerDialog
dark themeTimePickerDialog
has a dark theme that can be set by callingtpd.setThemeDark(true);
DatePickerDialog
dark theme
The DatePickerDialog
has a dark theme that can be set by callingdpd.setThemeDark(true);
setAccentColor(String color)
and setAccentColor(int color)
Set the accentColor to be used by the Dialog. The String version parses the color out using Color.parseColor()
. The int version requires a ColorInt bytestring. It will explicitly set the color to fully opaque.
setOkColor()
and setCancelColor()
Set the text color for the OK or Cancel button. Behaves similar to setAccentColor()
TimePickerDialog
setTitle(String title)
Shows a title at the top of the TimePickerDialog
DatePickerDialog
setTitle(String title)
Shows a title at the top of the DatePickerDialog
instead of the day of the week
setOkText()
and setCancelText()
Set a custom text for the dialog Ok and Cancel labels. Can take a resourceId of a String. Works in both the DatePickerDialog and TimePickerDialog
setMinTime(Timepoint time)
Set the minimum valid time to be selected. Time values earlier in the day will be deactivated
setMaxTime(Timepoint time)
Set the maximum valid time to be selected. Time values later in the day will be deactivated
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
setSelectableDays(Calendar[] days)
You can pass a Calendar[]
to the DatePickerDialog
. The values in this list are the only acceptable dates for the picker. It takes precedence over setMinDate(Calendar day)
and setMaxDate(Calendar day)
setDisabledDays(Calendar[] days)
The values in this Calendar[]
are explicitly disabled (not selectable). This option can be used together with setSelectableDays(Calendar[] days)
: in case there is a clash setDisabledDays(Calendar[] days)
will take precedence over setSelectableDays(Calendar[] days)
setHighlightedDays(Calendar[] days)
You can pass a Calendar[]
of days to highlight. They will be rendered in bold. You can tweak the color of the highlighted days by overwriting mdtp_date_picker_text_highlighted
showYearPickerFirst(boolean yearPicker)
Show the year picker first, rather than the month and day picker.
OnDismissListener
and OnCancelListener
Both pickers can be passed a DialogInterface.OnDismissLisener
or DialogInterface.OnCancelListener
which allows you to run code when either of these events occur.
tpd.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
Log.d("TimePicker", "Dialog was cancelled");
}
});
vibrate(boolean vibrate)
Set whether the dialogs should vibrate the device when a selection is made. This defaults to true
.
dismissOnPause(boolean dismissOnPause)
Set whether the picker dismisses itself when the parent Activity is paused or whether it recreates itself when the Activity is resumed.
DatePickerDialog
autoDismiss(boolean autoDismiss)
If set to true
will dismiss the picker when the user selects a date. This defaults to false
.
TimepickerDialog
enableSeconds(boolean enableSconds)
and enableMinutes(boolean enableMinutes)
Allows you to enable or disable a seconds and minutes picker ont he TimepickerDialog
. Enabling the seconds picker, implies enabling the minutes picker. Disabling the minute picker will disable the seconds picker. The last applied setting will be used. By default enableSeconds = false
and enableMinutes = true
.
DatePickerDialog
setTimeZone(Timezone timezone)
Sets the Timezone
used to represent time internally in the picker. Defaults to the current default Timezone of the device.
DatePickerDialog
setDateRangeLimiter(DateRangeLimiter limiter)
Provide a custom implementation of DateRangeLimiter, giving you full control over which days are available for selection. This disables all of the other options that limit date selection.
SupportDialogFragment
?Not using the support library versions has been a well considered choice, based on the following considerations:
Fragments
, a number which will decrease even further going forward.SupportFragments
in your application, you can still use the normal FragmentManager
. Both can exist side by side.This means that in the current setup everyone can use the library: people using the support library and people not using the support library.
Finally changing to SupportDialogFragment
now will break the API for all the people using this library.
If you do really need SupportDialogFragment
, you can fork the library (It involves changing all of 2 lines of code, so it should be easy enough to keep it up to date with the upstream) or use this fork: https://github.com/infinum/MaterialDateTimePicker
dependencies {
compile 'co.infinum:materialdatetimepicker-support:3.2.2'
}
DatePickerDialog
return the selected month -1?In the java Calendar
class months use 0 based indexing: January is month 0, December is month 11. This convention is widely used in the java world, for example the native Android DatePicker.
DatePickerDialog
exposes some utility methods to enable / disable dates for common scenario's. If your needs are not covered by these, you can supply a custom implementation of the DateRangeLimiter
interface.
Because the DateRangeLimiter
is preserved when the Dialog
pauzes, your implementation must also implement Parcelable
.
class MyDateRangeLimiter implements DateRangeLimiter {
public MyDateRangeLimiter(Parcel in) {
}
@Override
public int getMinYear() {
return 1900;
}
@Override
public int getMaxYear() {
return 2100;
}
@Override
public Calendar getStartDate() {
Calendar output = Calendar.newInstance();
output.set(Calendar.YEAR, 1900);
output.set(Calendar.DAY_OF_MONTH, 1);
output.set(Calendar.MONTH, Calendar.JANUARY);
return output;
}
@Override
public Calendar getEndDate() {
Calendar output = Calendar.newInstance();
output.set(Calendar.YEAR, 2100);
output.set(Calendar.DAY_OF_MONTH, 1);
output.set(Calendar.MONTH, Calendar.JANUARY);
return output;
}
@Override
public boolean isOutOfRange(int year, int month, int day) {
return false;
}
@Override
public Calendar setToNearestDate(Calendar day) {
return day;
}
@Override
public void writeToParcel(Parcel out) {
}
@Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<MyDateRangeLimiter> CREATOR
= new Parcelable.Creator<MyDateRangeLimiter>() {
public MyDateRangeLimiter createFromParcel(Parcel in) {
return new MyDateRangeLimiter(in);
}
public MyDateRangeLimiter[] newArray(int size) {
return new MyDateRangeLimiter[size];
}
};
}
When you provide a custom DateRangeLimiter
the built-in methods for setting the enabled / disabled dates will no longer work. It will need to be completely handled by your implementation.
The simple solution is to dismiss the pickers when your activity is paused.
tpd.dismissOnPause(true);
If you do wish to retain the pickers when an orientation change occurs, things become a bit more tricky.
By default, when an orientation changes occurs android will destroy and recreate your entire Activity
. Wherever possible this library will retain its state on an orientation change. The only notable exceptions are the different callbacks and listeners. These interfaces are often implemented on Activities
or Fragments
. Naively trying to retain them would cause memory leaks. Apart from explicitly requiring that the callback interfaces are implemented on an Activity
, there is no safe way to properly retain the callbacks, that I'm aware off.
This means that it is your responsibility to set the listeners in your Activity
's onResume()
callback.
@Override
public void onResume() {
super.onResume();
DatePickerDialog dpd = (DatePickerDialog) getFragmentManager().findFragmentByTag("Datepickerdialog");
TimePickerDialog tpd = (TimePickerDialog) getFragmentManager().findFragmentByTag("TimepickerDialog");
if(tpd != null) tpd.setOnTimeSetListener(this);
if(dpd != null) dpd.setOnDateSetListener(this);
}
Copyright (c) 2015 Wouter Dullaert
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.