How to implement CalendarView in Android

Android does not offer any calendar view in the SDK. That is a big loss from the developer’s point of view. There are lots of situations where it would be beneficial to display days of a month and provide some option for the user to choose the day.

One solution is to use a 3rd party component. The second one is to implement one by your own, like I did.

Picture 1. CalendarView

When I started to implement  the calendar view, I googled around with some search terms and found this tip.

AFAIK, there are no other way than implement your own calendar. So… what you would have to do is using a GridLayout with 7 columns and create a custom BaseAdapter to display data correctly.

That sounded reasonable and I went ahead and tried it. My aim was to implement a single calendar view where user can navigate between months and choose a date (Picture 1). You can see the result here: https://github.com/nevalla/CalendarView

Basically two classes are needed to create the implementation mentioned above. One class to display calendar grid and the other one to adapt calendar days and items into the grid.

CalendarView.java

CalendarView is  a class that encapsulates the UI of the Calendar:  a header (navigation and name of the month) and a GridView.  onCreate() method does some initializations and res/layout/calendar.xml is set for the content view. Then handler attribute is used to populate some calendar items into to the calendar. Finally some event listeners are set. GridView’s OnClickListener returns selected date as string format:

gridview.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    	TextView date = (TextView)v.findViewById(R.id.date);
        if(date instanceof TextView && !date.getText().equals("")) {

        	Intent intent = new Intent();
        	String day = date.getText().toString();
        	if(day.length()==1) {
        		day = "0"+day;
        	}
        	// return selected date as string format
        	intent.putExtra("date", android.text.format.DateFormat.format("yyyy-MM", month)+"-"+day);
        	setResult(RESULT_OK, intent);
        	finish();
        }

    }
});

refreshCalendar() method asks calendar adapter to refresh itself and changes month name.
onNewItem() method captures date parameter and sets it as current date.

CalendarAdapter.java

CalendarAdapter is a class that handles the content of the calendar – how many days to display and whether to display calendar item icon or not.

refreshDays() method formats source array for the grid. Application assumes that weeks start on Monday, thus calculation is needed on how many empty days are before the first day of the month.

getView() method creates a view for each item referenced by the adapter. Layout of the view is defined in res/layout/calendar_item.xml.

CalendarViewSampleActivity.java

CalendarViewSampleActivity is an activity class that opens CalendarView. DatePicker’s date is updated by the return  value of the CalendarView.
So this is relatively simplified example of how to display calendar month and populate some items into it. How do you like it and how would you improve it?

UPDATE 1:

Since API level 11 (Android 3.0) there has been the native implementation of the CalendarView. However it’s just the view where you can pick a date, no calendar items can be shown.