Custom Calendar in android
Custom calendar is very important part in android . Using custom calendar we can easily customize calendar activity as per our requirements . I am describing how to create a custom calendar in android . Its very easy to integrate in eclipse as well as studio. I hope it will help you a lot . For create a custom calendar you have to follow these bellow steps . The steps are
1. Create a shape file "circile_cyan.xml" in your drawable folder .
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#00FFFF" >
</solid>
</shape>
2. Create a shape file "circile_grey.xml" in your drawable folder .
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#A9A9A9" >
</solid>
</shape>
3. Create a shape file "circile_white.xml" in your drawable folder .
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ffffff" >
</solid>
<stroke
android:width="0.5dp"
android:color="#000000" >
</stroke>
</shape>
4. Create a shape file "circile_white_with_black_border.xml" in your drawable folder .
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#FFFFFF" >
</solid>
<stroke android:color="#000000" android:width="0.5dp"></stroke>
</shape>
5. Create a class "Utility.java"
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
public class Utility {
public static ArrayList<String> nameOfEvent = new ArrayList<String>();
public static ArrayList<String> startDates = new ArrayList<String>();
public static ArrayList<String> endDates = new ArrayList<String>();
public static ArrayList<String> descriptions = new ArrayList<String>();
public static ArrayList<String> readCalendarEvent(Context context) {
Cursor cursor = context.getContentResolver()
.query(Uri.parse("content://com.android.calendar/events"),
new String[] { "calendar_id", "title", "description",
"dtstart", "dtend", "eventLocation" }, null,
null, null);
cursor.moveToFirst();
// fetching calendars name
String CNames[] = new String[cursor.getCount()];
// fetching calendars id
nameOfEvent.clear();
startDates.clear();
endDates.clear();
descriptions.clear();
for (int i = 0; i < CNames.length; i++) {
nameOfEvent.add(cursor.getString(1));
startDates.add(getDate(Long.parseLong(cursor.getString(3))));
endDates.add(getDate(Long.parseLong(cursor.getString(4))));
descriptions.add(cursor.getString(2));
CNames[i] = cursor.getString(1);
cursor.moveToNext();
}
return nameOfEvent;
}
@SuppressLint("SimpleDateFormat")
public static String getDate(long milliSeconds) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
return formatter.format(calendar.getTime());
}
}
6. Create a layout file "activity_cal.xml" for "CalenderActivity" class
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<LinearLayout
android:id="@+id/llHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/calendar_top"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="25"
android:orientation="horizontal">
<Button
android:id="@+id/btnPrevious"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Prev"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:orientation="horizontal">
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="Month"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="25"
android:orientation="horizontal">
<Button
android:id="@+id/btnNext"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Next"/>
</LinearLayout>
</LinearLayout>
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="7"
android:layout_below="@+id/llHeader">
</GridView>
</RelativeLayout>
7. Create a layout file "adapter_calendar_item.xml" for "CalendarAdapter" class
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/adapterCalender_llContainer"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="60"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:orientation="vertical">
<LinearLayout
android:id="@+id/adapterCalender_llEvent13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_tvEvent1"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="1dp"
android:background="@drawable/circile_white_with_black_border"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent2"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_cyan"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent3"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_grey"
android:text=""/>
</LinearLayout>
<LinearLayout
android:id="@+id/adapterCalender_llEvent46"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_tvEvent4"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="1dp"
android:background="@drawable/circile_cyan"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent5"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_grey"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent6"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_cyan"
android:text=""/>
</LinearLayout>
<LinearLayout
android:id="@+id/adapterCalender_llEvent79"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_tvEvent7"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="1dp"
android:background="@drawable/circile_grey"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent8"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_cyan"
android:text=""/>
<TextView
android:id="@+id/adapterCalender_tvEvent9"
android:layout_width="5dp"
android:layout_height="5dp"
android:textSize="10dp"
android:layout_margin="0.5dp"
android:background="@drawable/circile_white_with_black_border"
android:text=""/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_price"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="$300"
android:textSize="10dp"
android:singleLine="true"
android:paddingTop="3dp"
android:paddingRight="3dp"
android:textColor="#000000"
android:gravity="right|top">
</TextView>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="40"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_month"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="abcd"
android:paddingLeft="3dp"
android:textSize="10dp"
android:singleLine="true"
android:textColor="#000000"
android:gravity="left|center_vertical">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:orientation="horizontal">
<TextView
android:id="@+id/adapterCalender_date"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="abcd"
android:textSize="12dp"
android:paddingRight="3dp"
android:singleLine="true"
android:textColor="#000000"
android:gravity="right|center_vertical">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
7. In manifest file you have to give these two permissions
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
8. Create a class called "CalendarAdapter.java"
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@SuppressLint("InflateParams")
public class CalendarAdapter extends BaseAdapter {
private Context mContext;
// ApplicationStorage appStorage;
CalenderActivity mCalenderActivity;
private java.util.Calendar month;
public GregorianCalendar pmonth; // calendar instance for previous month
/**
* calendar instance for previous month for getting complete view
*/
public GregorianCalendar pmonthmaxset;
private GregorianCalendar selectedDate;
int firstDay;
int maxWeeknumber;
int maxP;
int calMaxP;
int lastWeekDay;
int leftDays;
int mnthlength;
String itemvalue, curentDateString;
DateFormat df;
private ArrayList<String> items;
public static List<String> dayString;
private View previousView;
public CalendarAdapter(Context c, GregorianCalendar monthCalendar,CalenderActivity activity) {
CalendarAdapter.dayString = new ArrayList<String>();
Locale.setDefault(Locale.US);
month = monthCalendar;
selectedDate = (GregorianCalendar) monthCalendar.clone();
mContext = c;
mCalenderActivity=activity;
//appStorage=(ApplicationStorage)mContext.getApplicationContext();
month.set(GregorianCalendar.DAY_OF_MONTH, 1);
this.items = new ArrayList<String>();
df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
curentDateString = df.format(selectedDate.getTime());
//appStorage.setSelectedDateInCalender(curentDateString);
refreshDays();
}
public void setItems(ArrayList<String> items) {
for (int i = 0; i != items.size(); i++) {
if (items.get(i).length() == 1) {
items.set(i, "0" + items.get(i));
}
}
this.items = items;
}
public int getCount() {
return dayString.size();
}
public Object getItem(int position) {
return dayString.get(position);
}
public long getItemId(int position) {
return 0;
}
// create a new view for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
TextView dayView,tvMonth,tvEvent1,tvEvent2,tvEvent3,tvEvent4,tvEvent5,tvEvent6,tvEvent7,tvEvent8,tvEvent9,tvPrice;
LinearLayout llContainer,llEvent13,llEvent46,llEvent79;
if (convertView == null) { // if it's not recycled, initialize some
// attributes
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.adapter_calendar_item ,null);
}
dayView = (TextView) v.findViewById(R.id.adapterCalender_date);
tvMonth=(TextView) v.findViewById(R.id.adapterCalender_month);
tvEvent1=(TextView) v.findViewById(R.id.adapterCalender_tvEvent1);
tvEvent2=(TextView) v.findViewById(R.id.adapterCalender_tvEvent2);
tvEvent3=(TextView) v.findViewById(R.id.adapterCalender_tvEvent3);
tvEvent4=(TextView) v.findViewById(R.id.adapterCalender_tvEvent4);
tvEvent5=(TextView) v.findViewById(R.id.adapterCalender_tvEvent5);
tvEvent6=(TextView) v.findViewById(R.id.adapterCalender_tvEvent6);
tvEvent7=(TextView) v.findViewById(R.id.adapterCalender_tvEvent7);
tvEvent8=(TextView) v.findViewById(R.id.adapterCalender_tvEvent8);
tvEvent9=(TextView) v.findViewById(R.id.adapterCalender_tvEvent9);
tvPrice=(TextView) v.findViewById(R.id.adapterCalender_price);
llContainer=(LinearLayout)v.findViewById(R.id.adapterCalender_llContainer);
llEvent13=(LinearLayout)v.findViewById(R.id.adapterCalender_llEvent13);
llEvent46=(LinearLayout)v.findViewById(R.id.adapterCalender_llEvent46);
llEvent79=(LinearLayout)v.findViewById(R.id.adapterCalender_llEvent79);
tvMonth.setText("");
//tvEvent1.setText("0");
//tvEvent2.setText("0");
tvPrice.setText("$300");
// separates daystring into parts.
String[] separatedTime = dayString.get(position).split("-");
// taking last part of date. ie; 2 from 2012-12-02
String gridvalue = separatedTime[2].replaceFirst("^0*", "");
//System.out.println("gridvalue :: "+gridvalue);
// checking whether the day is in current month or not.
if ((Integer.parseInt(gridvalue) > 1) && (position < firstDay)) {
// setting offdays to white color.
dayView.setTextColor(Color.BLACK);
dayView.setClickable(false);
dayView.setFocusable(false);
v.setBackgroundResource(R.drawable.circile_white);
} else if ((Integer.parseInt(gridvalue) < 7) && (position > 28)) {
dayView.setTextColor(Color.BLACK);
dayView.setClickable(false);
dayView.setFocusable(false);
v.setBackgroundResource(R.drawable.circile_white);
} else {
// setting curent month's days in black color.
dayView.setTextColor(Color.BLACK);
/* check the date is current date or not */
if (dayString.get(position).equals(curentDateString)) {
//System.out.println("curentDateString in view : "+curentDateString);
dayView.setTextColor(Color.RED);
setSelected(v);
previousView = v;
/* if user visit in current month then stop previous button functionality */
mCalenderActivity.disablePreviousButton(true);
} else {
v.setBackgroundResource(R.drawable.circile_white);
}
}
/* show month name on first day of every month */
if(Integer.parseInt(gridvalue)==1){
tvMonth.setText(getMonth(separatedTime[1].replaceFirst("^0*", "")));
}
/* set day value of every month */
dayView.setText(gridvalue);
// create date string for comparison
String date = dayString.get(position);
if (date.length() == 1) {
date = "0" + date;
}
String monthStr = "" + (month.get(GregorianCalendar.MONTH) + 1);
if (monthStr.length() == 1) {
monthStr = "0" + monthStr;
}
final int index=position;
llContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date1 = sdf.parse(dayString.get(index));
Date date2 = sdf.parse(curentDateString);
if(date1.before(date2)){
Toast.makeText(mContext,"Before today.",Toast.LENGTH_LONG).show();
}else {
Toast.makeText(mContext,"After today.",Toast.LENGTH_LONG).show();
}
} catch (ParseException e) {
e.printStackTrace();
}
}
});
return v;
}
public View setSelected(View view) {
if (previousView != null) {
previousView.setBackgroundResource(R.drawable.circile_white);
}
previousView = view;
view.setBackgroundResource(R.drawable.circile_white);
return view;
}
public void refreshDays() {
// clear items
items.clear();
dayString.clear();
Locale.setDefault(Locale.US);
pmonth = (GregorianCalendar) month.clone();
// month start day. ie; sun, mon, etc
firstDay = month.get(GregorianCalendar.DAY_OF_WEEK);
// finding number of weeks in current month.
maxWeeknumber = month.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH);
// allocating maximum row number for the gridview.
mnthlength = maxWeeknumber * 7;
maxP = getMaxP(); // previous month maximum day 31,30....
calMaxP = maxP - (firstDay - 1);// calendar offday starting 24,25 ...
/**
* Calendar instance for getting a complete gridview including the three
* month's (previous,current,next) dates.
*/
pmonthmaxset = (GregorianCalendar) pmonth.clone();
/**
* setting the start date as previous month's required date.
*/
pmonthmaxset.set(GregorianCalendar.DAY_OF_MONTH, calMaxP + 1);
/**
* filling calendar gridview.
*/
for (int n = 0; n < mnthlength; n++) {
itemvalue = df.format(pmonthmaxset.getTime());
pmonthmaxset.add(GregorianCalendar.DATE, 1);
dayString.add(itemvalue);
}
}
private int getMaxP() {
int maxP;
if (month.get(GregorianCalendar.MONTH) == month
.getActualMinimum(GregorianCalendar.MONTH)) {
pmonth.set((month.get(GregorianCalendar.YEAR) - 1),
month.getActualMaximum(GregorianCalendar.MONTH), 1);
} else {
pmonth.set(GregorianCalendar.MONTH,
month.get(GregorianCalendar.MONTH) - 1);
}
maxP = pmonth.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
return maxP;
}
private String getMonth(String month){
String strMonth="";
switch (month){
case "1":
strMonth="Jan";
break;
case "2":
strMonth="Feb";
break;
case "3":
strMonth="Mar";
break;
case "4":
strMonth="Apr";
break;
case "5":
strMonth="May";
break;
case "6":
strMonth="Jun";
break;
case "7":
strMonth="Jul";
break;
case "8":
strMonth="Aug";
break;
case "9":
strMonth="Sep";
break;
case "10":
strMonth="Oct";
break;
case "11":
strMonth="Nov";
break;
case "12":
strMonth="Dec";
break;
default:
strMonth="";
break;
}
return strMonth;
}
}
9. Create a activity class "CalenderActivity.java"
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.Locale;
import app.demo.utils.Utility;
public class CalenderActivity extends Activity {
Context context;
//--------------CUSTOM CALENDER -------------
public GregorianCalendar month, itemmonth;// calendar instances.
public CalendarAdapter adapter;// adapter instance
public Handler handler;// for grabbing some event values for showing the dot
// marker.
public ArrayList<String> items; // container to store calendar items which
// needs showing the event marker
ArrayList<String> event;
LinearLayout rLayout;
ArrayList<String> date;
ArrayList<String> desc;
GridView gridview;
TextView title;
Button previous,next;
//------------------------END---------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_jobhistory);
context=this;
month = (GregorianCalendar) GregorianCalendar.getInstance();
itemmonth = (GregorianCalendar) month.clone();
items = new ArrayList<String>();
adapter = new CalendarAdapter(context, month,CalenderActivity.this);
handler = new Handler();
handler.post(calendarUpdater);
gridview = (GridView)findViewById(R.id.gridview);
title = (TextView)findViewById(R.id.tvTitle);
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
previous = (Button)findViewById(R.id.btnPrevious);
next = (Button)findViewById(R.id.btnNext);
gridview.setAdapter(adapter);
previous.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
disablePreviousButton(false);
setPreviousMonth();
refreshCalendar();
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
disablePreviousButton(false);
setNextMonth();
refreshCalendar();
}
});
}
protected void setNextMonth() {
if (month.get(GregorianCalendar.MONTH) == month
.getActualMaximum(GregorianCalendar.MONTH)) {
month.set((month.get(GregorianCalendar.YEAR) + 1),
month.getActualMinimum(GregorianCalendar.MONTH), 1);
} else {
month.set(GregorianCalendar.MONTH,
month.get(GregorianCalendar.MONTH) + 1);
}
}
protected void setPreviousMonth() {
if (month.get(GregorianCalendar.MONTH) == month
.getActualMinimum(GregorianCalendar.MONTH)) {
month.set((month.get(GregorianCalendar.YEAR) - 1),
month.getActualMaximum(GregorianCalendar.MONTH), 1);
} else {
month.set(GregorianCalendar.MONTH,
month.get(GregorianCalendar.MONTH) - 1);
}
}
public void refreshCalendar() {
adapter.refreshDays();
adapter.notifyDataSetChanged();
handler.post(calendarUpdater); // generate some calendar items
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
}
public Runnable calendarUpdater = new Runnable() {
@Override
public void run() {
items.clear();
// Print dates of the current week
DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
String itemvalue;
event = Utility.readCalendarEvent(context);
Log.d("=====Event====", event.toString());
Log.d("=====Date ARRAY====", Utility.startDates.toString());
for (int i = 0; i < Utility.startDates.size(); i++) {
itemvalue = df.format(itemmonth.getTime());
itemmonth.add(GregorianCalendar.DATE, 1);
items.add(Utility.startDates.get(i).toString());
}
adapter.setItems(items);
adapter.notifyDataSetChanged();
//btnDetails.setText(appStorage.getSelectedDateInCalender());
}
};
public void disablePreviousButton(boolean isConditionMatched){
if(isConditionMatched){
previous.setClickable(false);
previous.setEnabled(false);
}else {
previous.setClickable(true);
previous.setEnabled(true);
}
}
}
10. Add "calendar_top.png" file in drawable folder Find Us :
Facebook : @apnaandroid
Google+ : Apna Java
Youtube : Android & Java Tutorial
Comments
Post a Comment