Updated: 07 April 2013
Tested in:
HTC desire S (android 2.3.5), Samsung Galaxy Ace (android 2.3.4), Samsung Galaxy Tab P3100 (android 4.0.4)
Base on:
Eclipse Indigo build in 20120216-1857, Java 1.6, Android 4.1.2
Download Source code:
DemoDialogCalendar20130407.rar
Description:
Open calendar in dialog and select date.
Screen shot:
Tutorial:
1. Create Calendar layouts:
calendar_day_gridcell.xml: layout for days.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/calendar_button_selector"> <Button android:id="@+id/calendar_day_gridcell" android:layout_gravity="center" android:textColor="#FFFFFF" android:background="@drawable/calendar_button_selector" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> <TextView android:id="@+id/num_events_per_day" style="@style/calendar_event_style" android:layout_gravity="right" android:layout_width="10dip" android:layout_height="10dip"> </TextView> </RelativeLayout>
simple_calendar_view.xml: layout for calendar dialog.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ffffff"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/prevMonth" android:src="@drawable/calendar_left_arrow_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"> </ImageView> <Button android:id="@+id/currentMonth" android:layout_weight="0.6" android:textColor="#FFFFFF" android:textAppearance="?android:attr/textAppearanceMedium" android:background="@drawable/calendar_bar" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> <ImageView android:id="@+id/nextMonth" android:src="@drawable/calendar_right_arrow_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"> </ImageView> </LinearLayout> <LinearLayout android:layout_gravity="center" android:layout_marginTop="2dp" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/calendarheader" android:src="@drawable/blue_bg_with_text" android:layout_gravity="center" android:layout_width="fill_parent" android:layout_height="wrap_content"> </ImageView> </LinearLayout> <GridView android:id="@+id/calendar" android:numColumns="7" android:layout_width="fill_parent" android:layout_height="wrap_content"> </GridView> </LinearLayout>
2. Create class for calendar controller:
public class GridCellAdapter extends BaseAdapter implements OnClickListener { private static final String tag = "GridCellAdapter"; private final Context _context; private final List<String> list; private static final int DAY_OFFSET = 1; private final String[] weekdays = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; private final String[] months = { getResources().getString(R.string.calendar_month_jan), getResources().getString(R.string.calendar_month_feb), getResources().getString(R.string.calendar_month_mar), getResources().getString(R.string.calendar_month_apr), getResources().getString(R.string.calendar_month_may), getResources().getString(R.string.calendar_month_jun), getResources().getString(R.string.calendar_month_jul), getResources().getString(R.string.calendar_month_aug), getResources().getString(R.string.calendar_month_sep), getResources().getString(R.string.calendar_month_oct), getResources().getString(R.string.calendar_month_nov), getResources().getString(R.string.calendar_month_dec) }; private final int[] daysOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; private final int month, year; private int daysInMonth, prevMonthDays; private int currentDayOfMonth; private int currentWeekDay; private Button gridcell; private TextView num_events_per_day; private final HashMap eventsPerMonthMap; private final SimpleDateFormat dateFormatter = new SimpleDateFormat( "dd-MMM-yyyy"); // Days in Current Month public GridCellAdapter(Context context, int textViewResourceId, int month, int year) { super(); this._context = context; this.list = new ArrayList<String>(); this.month = month; this.year = year; Calendar calendar = Calendar.getInstance(); setCurrentDayOfMonth(calendar.get(Calendar.DAY_OF_MONTH)); setCurrentWeekDay(calendar.get(Calendar.DAY_OF_WEEK)); Log.d(tag, "New Calendar:= " + calendar.getTime().toString()); Log.d(tag, "CurrentDayOfWeek :" + getCurrentWeekDay()); Log.d(tag, "CurrentDayOfMonth :" + getCurrentDayOfMonth()); // Print Month printMonth(month, year); // Find Number of Events eventsPerMonthMap = findNumberOfEventsPerMonth(year, month); } private String getMonthAsString(int i) { return months[i]; } private String getWeekDayAsString(int i) { return weekdays[i]; } private int getNumberOfDaysOfMonth(int i) { return daysOfMonth[i]; } public String getItem(int position) { return list.get(position); } @Override public int getCount() { return list.size(); } private void printMonth(int mm, int yy) { Log.d(tag, "==> printMonth: mm: " + mm + " " + "yy: " + yy); // The number of days to leave blank at // the start of this month. int trailingSpaces = 0; int leadSpaces = 0; int daysInPrevMonth = 0; int prevMonth = 0; int prevYear = 0; int nextMonth = 0; int nextYear = 0; int currentMonth = mm - 1; String currentMonthName = getMonthAsString(currentMonth); daysInMonth = getNumberOfDaysOfMonth(currentMonth); Log.d(tag, "Current Month: " + " " + currentMonthName + " having " + daysInMonth + " days."); // Gregorian Calendar : MINUS 1, set to FIRST OF MONTH GregorianCalendar cal = new GregorianCalendar(yy, currentMonth, 1); Log.d(tag, "Gregorian Calendar:= " + cal.getTime().toString()); if (currentMonth == 11) { prevMonth = currentMonth - 1; daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth); nextMonth = 0; prevYear = yy; nextYear = yy + 1; Log.d(tag, "*->PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear); } else if (currentMonth == 0) { prevMonth = 11; prevYear = yy - 1; nextYear = yy; daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth); nextMonth = 1; Log.d(tag, "**--> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear); } else { prevMonth = currentMonth - 1; nextMonth = currentMonth + 1; nextYear = yy; prevYear = yy; daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth); Log.d(tag, "***---> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear); } // Compute how much to leave before before the first day of the // month. // getDay() returns 0 for Sunday. int currentWeekDay = cal.get(Calendar.DAY_OF_WEEK) - 1; trailingSpaces = currentWeekDay; Log.d(tag, "Week Day:" + currentWeekDay + " is " + getWeekDayAsString(currentWeekDay)); Log.d(tag, "No. Trailing space to Add: " + trailingSpaces); Log.d(tag, "No. of Days in Previous Month: " + daysInPrevMonth); if (cal.isLeapYear(cal.get(Calendar.YEAR)) && mm == 2) { ++daysInMonth; } // Trailing Month days for (int i = 0; i < trailingSpaces; i++) { Log.d(tag, "PREV MONTH:= " + prevMonth + " => " + getMonthAsString(prevMonth) + " " + String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i)); list.add(String .valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i) + "-GREY" + "-" + getMonthAsString(prevMonth) + "-" + prevYear); } // Current Month Days for (int i = 1; i <= daysInMonth; i++) { Log.d(currentMonthName, String.valueOf(i) + " " + getMonthAsString(currentMonth) + " " + yy); if (i == getCurrentDayOfMonth() && (currentMonth == _calendar.get(Calendar.MONTH)) && (year == _calendar.get(Calendar.YEAR))) { list.add(String.valueOf(i) + "-BLUE" + "-" + getMonthAsString(currentMonth) + "-" + yy); } else { list.add(String.valueOf(i) + "-WHITE" + "-" + getMonthAsString(currentMonth) + "-" + yy); } } // Leading Month days for (int i = 0; i < list.size() % 7; i++) { Log.d(tag, "NEXT MONTH:= " + getMonthAsString(nextMonth)); list.add(String.valueOf(i + 1) + "-GREY" + "-" + getMonthAsString(nextMonth) + "-" + nextYear); } } /** * NOTE: YOU NEED TO IMPLEMENT THIS PART Given the YEAR, MONTH, retrieve * ALL entries from a SQLite database for that month. Iterate over the * List of All entries, and get the dateCreated, which is converted into * day. * * @param year * @param month * @return */ private HashMap findNumberOfEventsPerMonth(int year, int month) { HashMap map = new HashMap<String, Integer>(); return map; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; if (row == null) { LayoutInflater inflater = (LayoutInflater) _context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false); } // Get a reference to the Day gridcell gridcell = (Button) row.findViewById(R.id.calendar_day_gridcell); gridcell.setOnClickListener(this); // ACCOUNT FOR SPACING Log.d(tag, "Current Day: " + getCurrentDayOfMonth()); String[] day_color = list.get(position).split("-"); String theday = day_color[0]; String themonth = day_color[2]; String theyear = day_color[3]; if ((!eventsPerMonthMap.isEmpty()) && (eventsPerMonthMap != null)) { if (eventsPerMonthMap.containsKey(theday)) { num_events_per_day = (TextView) row .findViewById(R.id.num_events_per_day); Integer numEvents = (Integer) eventsPerMonthMap.get(theday); num_events_per_day.setText(numEvents.toString()); } } // Set the Day GridCell gridcell.setText(theday); gridcell.setTag(theday + "-" + themonth + "-" + theyear); Log.d(tag, "Setting GridCell " + theday + "-" + themonth + "-" + theyear); if (day_color[1].equals("GREY")) { gridcell.setTextColor(Color.DKGRAY); } if (day_color[1].equals("WHITE")) { gridcell.setTextColor(Color.WHITE); } if (day_color[1].equals("BLUE")) { gridcell.setTextColor(Color.YELLOW); // gridcell.setTextColor(getResources().getColor( // R.color.static_text_color)); } return row; } @Override public void onClick(View view) { String date_month_year = (String) view.getTag(); // selectedDayMonthYearButton.setText("Selected: " + // date_month_year); setSelectedDate(date_month_year); try { Date parsedDate = dateFormatter.parse(date_month_year); Log.d(tag, "Parsed Date: " + parsedDate.toString()); setSelectedDate(date_month_year); } catch (ParseException e) { e.printStackTrace(); } } public int getCurrentDayOfMonth() { return currentDayOfMonth; } private void setCurrentDayOfMonth(int currentDayOfMonth) { this.currentDayOfMonth = currentDayOfMonth; } public void setCurrentWeekDay(int currentWeekDay) { this.currentWeekDay = currentWeekDay; } public int getCurrentWeekDay() { return currentWeekDay; } }
References:
developer.android.com/reference/android/app/Dialog.html
developer.android.com/reference/java/util/Calendar.html