In this tutorial, we’ll be discussing the Calendar Widget using the CalendarView class in our Android Application.
Android Calendar View
As the name suggests, a Calendar View is used to display and select dates of the Calendar.
To add a CalendarView in the XML Layout do the following:
<CalendarView
android:id="@+id/calendarView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
This is how it looks in the Layout Design editor :
When you’ll run the above application on your device, it’ll show the current date. By default, the Calendar shows the Jan 1, 1970, date.
android:maxDate
and android:minDate
are used to set a custom range on the calendar. The dates specified are of the format MM/dd/yyyy.
To do the same in Java we use setMaxDate()
and setMinDate()
methods passing the long
instance. The getters methods are available for the same.
To set the current date we do setDate(long date)
on the CalendarView instance.
The setDate
method has another form: setDate(long date, boolean animate, boolean center)
.
By default the second and third parameters are true. When you select a new date it animates to it.
To change the date and week text style we use the attributes:
android:dateTextAppearance
and android:weekTextAppearance
or their equivalent setters in Java.
The CalendarView consists of the following listener:
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView calendarView, int i, int i1, int i2) {
}
});
This gets triggered whenever the date is changed by the user.
- i = year
- i1 = month
- i2 = day
In the following section, we’ll create an android application with a custom theme and add a custom range on the CalendarView along with showing the difference between animation and non-animation date changes.
Project Structure
Code
In the styles.xml file add the following three styles:
<style name="CalenderViewCustom" parent="Theme.AppCompat">
<item name="colorAccent">@android:color/holo_blue_dark</item>
<item name="colorPrimary">@android:color/darker_gray</item>
<item name="android:textColorPrimary">@color/colorPrimary</item>
</style>
<style name="CalenderViewDateCustomText" parent="android:TextAppearance.DeviceDefault.Small">
<item name="android:textColor">@android:color/holo_orange_dark</item>
</style>
<style name="CalenderViewWeekCustomText" parent="android:TextAppearance.DeviceDefault.Small">
<item name="android:textColor">@android:color/holo_green_dark</item>
</style>
android:textColorPrimary
by default is white. This color is set on the month date and the left and right indicators.
The code for the activity_main.xml is given below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<CalendarView
android:id="@+id/calendarView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dateTextAppearance="@style/CalenderViewDateCustomText"
android:theme="@style/CalenderViewCustom"
android:weekDayTextAppearance="@style/CalenderViewWeekCustomText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnWithAnim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="WithnAnim"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnWithoutAnim"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnRange" />
<Button
android:id="@+id/btnWithoutAnim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WithoutnAnim"
app:layout_constraintBaseline_toBaselineOf="@+id/btnWithAnim"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnWithAnim" />
<Button
android:id="@+id/btnRange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CustomnRange"
app:layout_constraintEnd_toStartOf="@+id/btnWithAnim"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/btnWithAnim" />
</android.support.constraint.ConstraintLayout>
We’ve added all the custom styles in the layout above.
The three Buttons are chained in the Constraint Layout.
The code for the MainActivity.java is given below:
package com.journaldev.androidcalendarview;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Calendar calendar;
CalendarView calendarView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, Calendar.NOVEMBER);
calendar.set(Calendar.DAY_OF_MONTH, 9);
calendar.set(Calendar.YEAR, 2012);
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.YEAR, 1);
calendarView = findViewById(R.id.calendarView);
Button btnRange = findViewById(R.id.btnRange);
btnRange.setOnClickListener(this);
Button btnWithoutAnim = findViewById(R.id.btnWithoutAnim);
btnWithoutAnim.setOnClickListener(this);
Button btnWithAnim = findViewById(R.id.btnWithAnim);
btnWithAnim.setOnClickListener(this);
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView calendarView, int i, int i1, int i2) {
String msg = "Selected date Day: " + i2 + " Month : " + (i1 + 1) + " Year " + i;
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnWithAnim:
calendarView.setDate(calendar.getTimeInMillis(), true, true);
break;
case R.id.btnWithoutAnim:
calendar.set(Calendar.DAY_OF_MONTH, 12);
calendar.set(Calendar.YEAR, 2016);
calendar.add(Calendar.MONTH, Calendar.MARCH);
calendarView.setDate(calendar.getTimeInMillis(), false, false);
break;
case R.id.btnRange:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
long endOfMonth = calendar.getTimeInMillis();
calendar = Calendar.getInstance();
calendar.set(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
long startOfMonth = calendar.getTimeInMillis();
calendarView.setMaxDate(endOfMonth);
calendarView.setMinDate(startOfMonth);
String minDateString = new SimpleDateFormat("MM/dd/yyyy").format(new Date(calendarView.getMinDate()));
String maxDateString = new SimpleDateFormat("MM/dd/yyyy").format(new Date(calendarView.getMaxDate()));
Toast.makeText(getApplicationContext(), "MMDDYYYY Min date - " + minDateString + " Max Date is " + maxDateString, Toast.LENGTH_LONG).show();
break;
}
}
}
calendar.getActualMaximum(Calendar.DATE)
gets the end of the month for the current date.
We’ve used SimpleDateFormat
to convert the dates into a custom format.
The output of the application in action is given below:
In the first case, we animate to another date with animation. In the last case, the custom range shows only the July Month. The indicators are disabled.
This brings an end to this tutorial. You can download the project from the link below: