Android is already packed with great Calender and Timepicker to add-in application. Which most of the time fulfill basic requirements needs of a project. But some times few challenges come on ways which call for more flexibilities in Calander date pickers.
A few days back I was working on a project with Booking appointment module. There was a requirement to disable all Sundays and Saturdays in calendar datepicker dialog so that nobody will be able to select disabled dates. But there is no possibility to achieve that in traditional datepicker Calender.
After some research, I came across a good substitute for Date and Time pickers in Android application. Android Material Date and Time picker is already a choice of many developers and its creator Wdullaer really quick on updates and fixes.
Here we will get to know how to implement Android Material Date and Timepicker in the application and also discuss some of the major methods available and will also explore its important options.
Let’s start with a new Android project, here my Android Studio’s current version is v3.4.2
Create a new project with the “Empty” template.
Open Module app’s build.gradle file then add following in dependencies
... ... dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' compile 'com.wdullaer:materialdatetimepicker:3.6.4' }
After that click on “Sync Now” to make changes and download package.
Next, we will add Two Buttons “Open Datepicker” and “Open Timepicker” and Two text fields to show selected values.
Now open “~activity_main.xml” file then replace following XML layout code in it.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button_datepicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Open Datepicker"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.508"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_datepicker"
android:layout_width="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="88dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Select Date"
android:textSize="36sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_datepicker"
android:layout_height="50dp" />
<Button
android:id="@+id/button_timepicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="104dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Open Timepicker"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_datepicker" />
<TextView
android:id="@+id/text_timepicker"
android:layout_width="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="112dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Select Time"
android:textSize="36sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_timepicker"
android:layout_height="50dp" />
</android.support.constraint.ConstraintLayout>
In MainActivity.java file we will call Datepicker and Timepicker methods after adding click listeners on Buttons we added in our layout file.
Import packages required in the file
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
also, implement interfaces to add callbacks for After selection of values from the date and time picker.
public class MainActivity extends AppCompatActivity implements
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener
{
...
...
Define some variables to keep date and time and also Datetime dialog instances
DatePickerDialog datePickerDialog ;
TimePickerDialog timePickerDialog ;
int Year, Month, Day, Hour, Minute;
Calendar calendar ;
In the onCreate method, we will add click listeners will call Datepicker and Timepicker dialogs
Datepicker
final Button button_datepicker = (Button) findViewById(R.id.button_datepicker);
button_datepicker.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
datePickerDialog = DatePickerDialog.newInstance(MainActivity.this, Year, Month, Day);
datePickerDialog.setThemeDark(false);
datePickerDialog.showYearPickerFirst(false);
datePickerDialog.setTitle("Date Picker");
datePickerDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
Toast.makeText(MainActivity.this, "Datepicker Canceled", Toast.LENGTH_SHORT).show();
}
});
datePickerDialog.show(getFragmentManager(), "DatePickerDialog");
}
});
Timepicker
final Button button_timepicker = (Button) findViewById(R.id.button_timepicker);
button_timepicker.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
timePickerDialog = TimePickerDialog.newInstance(MainActivity.this, Hour, Minute,false );
timePickerDialog.setThemeDark(false);
//timePickerDialog.showYearPickerFirst(false);
timePickerDialog.setTitle("Time Picker");
timePickerDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
Toast.makeText(MainActivity.this, "Timepicker Canceled", Toast.LENGTH_SHORT).show();
}
});
timePickerDialog.show(getFragmentManager(), "TimePickerDialog");
}
});
Now let’s add callback methods onDateSet for date and onTimeSet time to get selected values
@Override
public void onDateSet(DatePickerDialog view, int Year, int Month, int Day) {
String date = "Date: "+Day+"/"+(Month+1)+"/"+Year;
Toast.makeText(MainActivity.this, date, Toast.LENGTH_LONG).show();
TextView text_datepicker = (TextView)findViewById(R.id.text_datepicker);
text_datepicker.setText(date);
}
@Override
public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) {
String time = "Time: "+hourOfDay+"h"+minute+"m"+second;
Toast.makeText(MainActivity.this, time, Toast.LENGTH_LONG).show();
TextView text_timepicker = (TextView)findViewById(R.id.text_timepicker);
text_timepicker.setText(time);
}
Set Min Date and Max Date in Datepicker
To set Min and Max date validations we can use setMinDate() and setMaxDate() methods as follows
// Setting Min Date to today date
Calendar min_date_c = Calendar.getInstance();
datePickerDialog.setMinDate(min_date_c);
// Setting Max Date to next 2 years
Calendar max_date_c = Calendar.getInstance();
max_date_c.set(Calendar.YEAR, Year+2);
datePickerDialog.setMaxDate(max_date_c);
Disable specific dates in Datepicker
There are three very useful methods available which take Calander array of days.
setSelectableDays(Calendar[] days): The values in this list are the only acceptable dates for the picker.
setDisabledDays(Calendar[] days): The values in this Calendar[] are explicitly disabled (not selectable).
setHighlightedDays(Calendar[] days): Pass a Calendar[] of days to highlight.
Here is an example of Disable All SUNDAYS and SATURDAYS in Datepicker which are lying in between the Min and Max dates.
//Disable all SUNDAYS and SATURDAYS between Min and Max Dates
for (Calendar loopdate = min_date_c; min_date_c.before(max_date_c); min_date_c.add(Calendar.DATE, 1), loopdate = min_date_c) {
int dayOfWeek = loopdate.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY) {
Calendar[] disabledDays = new Calendar[1];
disabledDays[0] = loopdate;
datePickerDialog.setDisabledDays(disabledDays);
}
}
Our complete MainActivity will have the following code
package com.freakyjolly.materialdateandtimepicker;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.date.MonthAdapter;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import java.lang.reflect.Array;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class MainActivity extends AppCompatActivity implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
DatePickerDialog datePickerDialog ;
TimePickerDialog timePickerDialog ;
int Year, Month, Day, Hour, Minute;
Calendar calendar ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calendar = Calendar.getInstance();
Year = calendar.get(Calendar.YEAR) ;
Month = calendar.get(Calendar.MONTH);
Day = calendar.get(Calendar.DAY_OF_MONTH);
Hour = calendar.get(Calendar.HOUR_OF_DAY);
Minute = calendar.get(Calendar.MINUTE);
//getWeekendDays();
final Button button_datepicker = (Button) findViewById(R.id.button_datepicker);
button_datepicker.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
datePickerDialog = DatePickerDialog.newInstance(MainActivity.this, Year, Month, Day);
datePickerDialog.setThemeDark(false);
datePickerDialog.showYearPickerFirst(false);
datePickerDialog.setTitle("Date Picker");
// Setting Min Date to today date
Calendar min_date_c = Calendar.getInstance();
datePickerDialog.setMinDate(min_date_c);
// Setting Max Date to next 2 years
Calendar max_date_c = Calendar.getInstance();
max_date_c.set(Calendar.YEAR, Year+2);
datePickerDialog.setMaxDate(max_date_c);
//Disable all SUNDAYS and SATURDAYS between Min and Max Dates
for (Calendar loopdate = min_date_c; min_date_c.before(max_date_c); min_date_c.add(Calendar.DATE, 1), loopdate = min_date_c) {
int dayOfWeek = loopdate.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY) {
Calendar[] disabledDays = new Calendar[1];
disabledDays[0] = loopdate;
datePickerDialog.setDisabledDays(disabledDays);
}
}
datePickerDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
Toast.makeText(MainActivity.this, "Datepicker Canceled", Toast.LENGTH_SHORT).show();
}
});
datePickerDialog.show(getFragmentManager(), "DatePickerDialog");
}
});
final Button button_timepicker = (Button) findViewById(R.id.button_timepicker);
button_timepicker.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
timePickerDialog = TimePickerDialog.newInstance(MainActivity.this, Hour, Minute,false );
timePickerDialog.setThemeDark(false);
//timePickerDialog.showYearPickerFirst(false);
timePickerDialog.setTitle("Time Picker");
timePickerDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
Toast.makeText(MainActivity.this, "Timepicker Canceled", Toast.LENGTH_SHORT).show();
}
});
timePickerDialog.show(getFragmentManager(), "TimePickerDialog");
}
});
}
@Override
public void onDateSet(DatePickerDialog view, int Year, int Month, int Day) {
String date = "Date: "+Day+"/"+(Month+1)+"/"+Year;
Toast.makeText(MainActivity.this, date, Toast.LENGTH_LONG).show();
TextView text_datepicker = (TextView)findViewById(R.id.text_datepicker);
text_datepicker.setText(date);
}
@Override
public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) {
String time = "Time: "+hourOfDay+"h"+minute+"m"+second;
Toast.makeText(MainActivity.this, time, Toast.LENGTH_LONG).show();
TextView text_timepicker = (TextView)findViewById(R.id.text_timepicker);
text_timepicker.setText(time);
}
}
Conclusion: Android Material Date and Time picker are loaded with many configuration options. It is very easy to use and implement in a new or existing project. You can surely use this a substitute to Android’s default Calendar view.
Let me know if you are stuck to try something we can look and explore more into it.
Leave a Reply