Reputation: 3155
In my app, I have requirement of showing calendar. Since, calendar view is available from API level 11, so, I used grid view instead. Basically, I follwed this tutorial. Calendar is working, but data in Calendar in appearing with delay, means, when I click on button to display the calendar, it comes up after delay of around 5-10 seconds. I even tested with disabling the log, which I have put in the program, but it didn't made any difference. I am posting my code below.
Calendar Adapter
public class CalendarAdapter extends BaseAdapter //implements OnClickListener
{
static final int FIRST_DAY_OF_WEEK = 0; // Sunday = 0, Monday = 1
private Context mContext;
private Calendar month;
private Calendar selectedDate;
public String[] days;
TextView txtCurMonth;
public static final String TAG = "CalendarAdapter";
int curYear, curMonth;
public ArrayList<EventDetailDAO> mEventDAOList;
String date, dateToHighlight;
public static boolean calendarItemClicked = false;
ViewHolder holder;
public CalendarAdapter(Context c, Calendar monthCalendar, TextView txtCurMonth)
{
month = monthCalendar;
selectedDate = (Calendar)monthCalendar.clone();
mContext = c;
month.set(Calendar.DAY_OF_MONTH, 1);
new ArrayList<String>();
this.txtCurMonth = txtCurMonth;
mEventDAOList = new ArrayList<EventDetailDAO>();
curYear = selectedDate.get(Calendar.YEAR);
curMonth = selectedDate.get(Calendar.MONTH) + 1;
refreshDays();
}//Constructor
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));
}//if
}//for
}//setItems
public int getCount()
{
return days.length;
}//getCount
public Object getItem(int position)
{
return null;
}//getItem
public long getItemId(int position)
{
return 0;
}//getItemId
// create a new view for each item referenced by the Adapter
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
holder = new ViewHolder();
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.calendar_grid_adapter, null);
holder.linCalAdapParent = (LinearLayout)convertView
.findViewById(R.id.linCalAdapParent);
holder.dayView = (TextView)convertView.findViewById(R.id.date);
convertView.setTag(holder);
}//if
else
{
holder = (ViewHolder)convertView.getTag();
}//else
Typeface date_TF = Typeface.createFromAsset(mContext.getAssets(), "fonts/arial.ttf");
txtCurMonth.setTypeface(date_TF);
txtCurMonth.setText(DateFormat.format("MMMM yyyy", month.getTime()));
holder.dayView.setTypeface(date_TF);
holder.dayView.setText(days[position]);
if(days[position].equals(""))
{
holder.linCalAdapParent.setBackgroundResource(R.drawable.calendar_tile);
}//if
else
{
String monthToCheck = null;
if(curMonth < 10)
{
monthToCheck = "0"+curMonth;
}//if
else
{
monthToCheck = Integer.toString(curMonth);
}//else
dateToHighlight = curYear+"-"+monthToCheck;
Log.v(TAG, "date to highlight: "+dateToHighlight);
if(isEnabled(position))
{
holder.linCalAdapParent.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Log.v(TAG, "CalendarAdapter mEventDAOList size: "+mEventDAOList.size());
String daysToMatch = days[position];
if(daysToMatch.length() == 1)
{
daysToMatch = "0"+daysToMatch;
}//if
Log.v(TAG, "CalendarAdapter day selected: "+daysToMatch);
ArrayList<EventDetailDAO> mSelectedEventDAOList
= new ArrayList<EventDetailDAO>();
for(int i = 0; i < mEventDAOList.size(); i++)
{
if(mEventDAOList.get(i).getEvent_Date().contains(daysToMatch))
{
mSelectedEventDAOList.add(mEventDAOList.get(i));
selectedDate.set(Calendar.YEAR, curYear);
selectedDate.set(Calendar.MONTH, curMonth - 1);
selectedDate.set(Calendar.DAY_OF_MONTH, Integer.parseInt(daysToMatch));
}//if
}//for
((EventsActivity)mContext).getDataFromCalendar(mSelectedEventDAOList, selectedDate);
((EventsActivity)mContext).calInstanceFromAdapter = selectedDate;
calendarItemClicked = true;
}//onClick
});
}//if
}//else
Log.v(TAG, "Calendar adapter getView called");
return convertView;
}//getView
public void refreshDays()
{
// clear items
//items.clear();
int lastDay = month.getActualMaximum(Calendar.DAY_OF_MONTH);
int firstDay = (int)month.get(Calendar.DAY_OF_WEEK);
Log.v(TAG, "in refreshDays, lastDay: "+lastDay);
Log.v(TAG, "in refreshDays, firstDay: "+firstDay);
// figure size of the array
if(firstDay == 1)
{
Log.v(TAG, "if first day 1");
days = new String[lastDay + (FIRST_DAY_OF_WEEK * 6)];
}//if
else
{
Log.v(TAG, "else first day not 1");
days = new String[lastDay + firstDay - (FIRST_DAY_OF_WEEK + 1)];
}//else
int j=FIRST_DAY_OF_WEEK;
// populate empty days before first real day
if(firstDay > 1)
{
Log.v(TAG, "if first day > 1");
for(j = 0; j < firstDay - FIRST_DAY_OF_WEEK; j++)
{
Log.v(TAG, "in for if first day > 1");
days[j] = "";
}//for
}//if
else
{
Log.v(TAG, "else first day < 1");
for(j = 0; j < FIRST_DAY_OF_WEEK * 6; j++)
{
Log.v(TAG, "in for else first day < 1");
days[j] = "";
}//for
j = FIRST_DAY_OF_WEEK * 6 + 1; // sunday => 1, monday => 7
}//else
// populate days
int dayNumber = 1;
for(int i = j - 1; i < days.length; i++)
{
Log.v(TAG, "in for day number");
days[i] = "" + dayNumber;
dayNumber++;
}//for
}//refreshDays
@Override
public boolean isEnabled(int position)
{
date = days[position];
if(date.length() == 1)
{
date = "0"+date;
}//if
dateToHighlight = dateToHighlight+"-"+date;
for(EventDetailDAO mEventDetailDAO: GetEventDetailAsyncTask.mainEventDetailArrayList)
{
Log.v(TAG, "CalendarAdapter isEnabled dateToHighlight: "+dateToHighlight);
if(mEventDetailDAO.getEvent_Date().equals(dateToHighlight))
{
mEventDAOList.add(mEventDetailDAO);
holder.linCalAdapParent.setBackgroundResource(R.drawable.calendar_tile_sel);
return true;
}//if
}//for
return false;
}//isEnabled
class ViewHolder
{
LinearLayout linCalAdapParent;
TextView dayView;
}//ViewHolder
}//CalendarAdapter
In my calendar, I have to highlight the dates which have some event. And, on click of highlighted date, it will show the list of events on that date. Every thing is working. except the calendar appears with delay even if I change month. I am not getting the cause.
Upvotes: 0
Views: 701
Reputation: 16043
One of the possible causes of the delay may be the call to Typeface.createFromAsset()
which is called for every cell. The createFromAsset()
method consumes a lot of resources.
To mitigate this, you could create a singleton class that retains the typeface used, so the font is not generated from the font file every time. Or you initialize it in onCreate() and pass it as an argument to the CalendarAdapter
constructor and then use that instance in getView()
.
(To test this assumption comment the lines that sets the font to txtCurMonth
TextView, and see if any difference)
Upvotes: 1