Nitish
Nitish

Reputation: 3155

Android: Data in grid view appearing with delay

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

Answers (1)

Andy Res
Andy Res

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

Related Questions