Wednesday, September 25, 2013

Android Simple Calandar


In this tutorial, I would like to provide a way for creating your own Android Calendar. Feel free to improve and customize it.

Final Outcome:


Simple_calendar_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/backgrounddd"
    android:orientation="vertical" >

    <Button
        android:id="@+id/selectedDayMonthYear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/calendar_top_header"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#FFFFFF" >
    </Button>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/prevMonth"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@drawable/calandar_left_arrow_selecter" >
        </ImageView>

        <Button
            android:id="@+id/currentMonth"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.6"
            android:background="@drawable/calendar_bar"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="#FFFFFF" >
        </Button>

        <ImageView
            android:id="@+id/nextMonth"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@drawable/calandar_right_arroe_selecter" >
        </ImageView>
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" >

        <ImageView
            android:id="@+id/calendarheader"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/blue_bg_with_text" >
        </ImageView>
    </LinearLayout>

    <GridView
        android:id="@+id/calendar"
        android:layout_width="fill_parent"
        android:layout_height="208dp"
        android:layout_weight="0.02"
        android:numColumns="7" >
    </GridView>

    <Button
        android:id="@+id/pass_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Direct to add events"
        android:textSize="15sp"
        android:textStyle="bold" />

</LinearLayout>


calendar_day_grid_cell

<?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"
                   android:layout_width="10dip"
                   android:layout_height="10dip"
                   android:layout_gravity="right"
                   android:textColor="#ffff00" >

               </TextView>
</RelativeLayout>

Simple_Calandar.java

package com.example.moodle_app;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class Simple_Calandar extends Activity implements OnClickListener {

 private static final String tag = "SimpleCalendarViewActivity";

 private ImageView calendarToJournalButton;
 private Button selectedDayMonthYearButton;
 private Button currentMonth;
 private ImageView prevMonth;
 private ImageView nextMonth;
 private GridView calendarView;
 private GridCellAdapter adapter;
 private Calendar _calendar;
 private int month, year;
 private final DateFormat dateFormatter = new DateFormat();
 private static final String dateTemplate = "MMMM yyyy";
 String stuff;
 /** Called when the activity is first created. */@Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.simpel_calandar_view);
  Bundle bundle = getIntent().getExtras();
  //  Extract the data…
  stuff = bundle.getString("stuff");
  Button button2 = (Button) findViewById(R.id.pass_date);
  selectedDayMonthYearButton = (Button) this.findViewById(R.id.selectedDayMonthYear);
  button2.setOnClickListener(new OnClickListener() {


   public void onClick(View V) {
    if ((selectedDayMonthYearButton.getText().toString().equalsIgnoreCase(""))) {
     Toast.makeText(getApplicationContext(), "Please fill the required fields!!!! ", Toast.LENGTH_SHORT).show();

    } else {
     Intent in = new Intent(Simple_Calandar.this, DateTimePicker.class);

     Bundle bundle = new Bundle();
     //Add your data to bundle
     bundle.putString("date", selectedDayMonthYearButton.getText().toString());
     bundle.putString("stuff", stuff);
     //Add the bundle to the intent
     in
     .putExtras(bundle);

     //Fire that second activity
     startActivity( in );



    }
   }
  });
  _calendar = Calendar.getInstance(Locale.getDefault());
  month = _calendar.get(Calendar.MONTH) + 1;
  year = _calendar.get(Calendar.YEAR);
  Log.d(tag, "Calendar Instance:= " + "Month: " + month + " " + "Year: " + year);
  prevMonth = (ImageView) this.findViewById(R.id.prevMonth);
  prevMonth.setOnClickListener(this);

  currentMonth = (Button) this.findViewById(R.id.currentMonth);
  currentMonth.setText(dateFormatter.format(dateTemplate, _calendar.getTime()));

  nextMonth = (ImageView) this.findViewById(R.id.nextMonth);
  nextMonth.setOnClickListener(this);

  calendarView = (GridView) this.findViewById(R.id.calendar);

  // Initialised
  adapter = new GridCellAdapter(getApplicationContext(), R.id.calendar_day_gridcell, month, year);
  adapter.notifyDataSetChanged();
  calendarView.setAdapter(adapter);
 }

 /**
  * 
  * @param month
  * @param year
  */
 private void setGridCellAdapterToDate(int month, int year) {
  adapter = new GridCellAdapter(getApplicationContext(), R.id.calendar_day_gridcell, month, year);
  _calendar.set(year, month - 1, _calendar.get(Calendar.DAY_OF_MONTH));
  currentMonth.setText(dateFormatter.format(dateTemplate, _calendar.getTime()));
  adapter.notifyDataSetChanged();
  calendarView.setAdapter(adapter);
 }

 @Override
 public void onClick(View v) {
  if (v == prevMonth) {
   if (month <= 1) {
    month = 12;
    year--;
   } else {
    month--;
   }
   Log.d(tag, "Setting Prev Month in GridCellAdapter: " + "Month: " + month + " Year: " + year);
   setGridCellAdapterToDate(month, year);
  }
  if (v == nextMonth) {
   if (month > 11) {
    month = 1;
    year++;
   } else {
    month++;
   }
   Log.d(tag, "Setting Next Month in GridCellAdapter: " + "Month: " + month + " Year: " + year);
   setGridCellAdapterToDate(month, year);
  }

 }

 @Override
 public void onDestroy() {
  Log.d(tag, "Destroying View ...");
  super.onDestroy();
 }

 // ///////////////////////////////////////////////////////////////////////////////////////
 // Inner Class
 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 = {
   "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
  };
  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;

   Log.d(tag, "==> Passed in Date FOR Month: " + month + " " + "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();
  }

  /**
   * Prints Month
   * 
   * @param mm
   * @param yy
   */
  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 == 1) {
    ++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()) {
     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);
   }
  }
  private HashMap findNumberOfEventsPerMonth(int year, int month) {
   HashMap map = new HashMap < String, Integer > ();
   // DateFormat dateFormatter2 = new DateFormat();
   //                                                                                       
   // String day = dateFormatter2.format("dd", dateCreated).toString();
   //
   // if (map.containsKey(day))
   // {
   // Integer val = (Integer) map.get(day) + 1;
   // map.put(day, val);
   // }
   // else
   // {
   // map.put(day, 1);
   // }
   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.calanda_day_grid_cell, 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.GRAY);
   }
   if (day_color[1].equals("WHITE")) {
    gridcell.setTextColor(Color.WHITE);
   }
   if (position % 7 == 0 || position % 7 == 6) {
    gridcell.setTextColor(Color.RED);
   }
   if (day_color[1].equals("BLUE")) {
    Calendar cal = Calendar.getInstance();

    if ((cal.get(Calendar.MONTH) + 1) == month) {
     // Which means today. 
     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(date_month_year);

   try {
    Date parsedDate = dateFormatter.parse(date_month_year);
    Log.d(tag, "Parsed Date: " + parsedDate.toString());

   } 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;
  }

 }
}

That's All :) :)
Thank You.




2 comments:

Blogger Widgets