3
\$\begingroup\$

I working on a calendar app on Android, using roomaorama, which is nice.

I am fetching all the events from Events table in Calendar provider once which seems not good performance wise.

The library uses a infinite view pager. It uses 4 adapters to display dates.

CaldroidGridAdapter adapter0 = getNewDatesGridAdapter(
            currentDateTime.getMonth(), currentDateTime.getYear());

// Setup dateInMonthsList
dateInMonthsList = adapter0.getDatetimeList();

// Next month
DateTime nextDateTime = currentDateTime.plus(0, 1, 0, 0, 0, 0, 0,
            DateTime.DayOverflow.LastDay);
CaldroidGridAdapter adapter1 = getNewDatesGridAdapter(
            nextDateTime.getMonth(), nextDateTime.getYear());

// Next 2 month
DateTime next2DateTime = nextDateTime.plus(0, 1, 0, 0, 0, 0, 0,
            DateTime.DayOverflow.LastDay);
CaldroidGridAdapter adapter2 = getNewDatesGridAdapter(
            next2DateTime.getMonth(), next2DateTime.getYear());

// Previous month
DateTime prevDateTime = currentDateTime.minus(0, 1, 0, 0, 0, 0, 0,
            DateTime.DayOverflow.LastDay);
CaldroidGridAdapter adapter3 = getNewDatesGridAdapter(
            prevDateTime.getMonth(), prevDateTime.getYear());

The library uses the date4j library for dates.

I am using asynctask for fetching events from calendar provider. Fetching events based on month change can be done using the below. But what if the user swipes at a faster rate (it's a view pager)?

final CaldroidListener listener = new CaldroidListener() {

    @Override
    public void onSelectDate(Date date, View view) {
        Toast.makeText(getApplicationContext(), formatter.format(date),
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onChangeMonth(int month, int year) {

       /* Do i fetch events here based on month */
        String text = "month: " + month + " year: " + year;
        Toast.makeText(getApplicationContext(), text,
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLongClickDate(Date date, View view) {
        Toast.makeText(getApplicationContext(),
                "Long click " + formatter.format(date),
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCaldroidViewCreated() {
        Toast.makeText(getApplicationContext(),
                "Caldroid view is created",
                Toast.LENGTH_SHORT).show();
    }

}; 

MyAsyncTask code

private class GetEvents extends AsyncTask<Integer, Void, ArrayList<Event>> {



        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            events.clear();
        }


        @Override
        protected ArrayList<Event> doInBackground(Integer... params) {

            Calendar c_start = Calendar.getInstance();

            String millisecond = String.valueOf(c_start.getTimeInMillis());

            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH,c_start.getActualMinimum(Calendar.DAY_OF_MONTH));
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 999);
            String emillisecond = String.valueOf(calendar.getTimeInMillis());

            selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
                    + Calendars.ACCOUNT_TYPE + " = ?) AND ("
                    + Calendars.OWNER_ACCOUNT + " = ?) AND (" + "dtstart"
                    + " >= ?))";
             selectionArgs = new String[] { "accountname",
                    "com.google", "accountname", millisecond};
            cursor = getContentResolver().query(
                    Uri.parse("content://com.android.calendar/events"),
                    new String[] { "calendar_id", "title", "description",
                            "dtstart", "dtend", "eventLocation" }, selection,
                    selectionArgs, null);
            if (cursor.moveToFirst() && cursor.getCount() > 1) {
                do {

                    Event event = new Event();
                    event.setEVENT(cursor.getString(1));
                    event.setDESCRIPTION(cursor.getString(2));

                    event.setStartDate(Long.parseLong(cursor.getString(3)));
                    event.setEndDate(Long.parseLong(cursor.getString(4)));
                    event.setLOCATION(cursor.getString(5));

                    events.add(event);
                } while (cursor.moveToNext());
                cursor.close();

            }else
            {
                cursor.close();
            }

            return events;
        }

        @Override
        protected void onPostExecute(ArrayList<Event> result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            for (int i = 0; i < result.size(); i++) {

                Calendar c = Calendar.getInstance();
                c.setTimeInMillis(Long.valueOf(result.get(i).getStartDate()));

                Date greenDate = c.getTime();


                if (caldroidFragment != null) {


                    caldroidFragment.setBackgroundResourceForDate(R.color.blue,
                            greenDate);

                    caldroidFragment.refreshView();

                } 

            }

        }

How the dates are populated?

In the adapter you have a array list of DateTime

protected ArrayList<DateTime> datetimeList;

Then

datetimeList = CalendarHelper.getFullWeeks(this.month, this.year,
            startDayOfWeek, sixWeeksInCalendar); 

Then

public static ArrayList<DateTime> getFullWeeks(int month, int year,
        int startDayOfWeek, boolean sixWeeksInCalendar) {
    ArrayList<DateTime> datetimeList = new ArrayList<DateTime>();

    DateTime firstDateOfMonth = new DateTime(year, month, 1, 0, 0, 0, 0);
    DateTime lastDateOfMonth = firstDateOfMonth.plusDays(firstDateOfMonth
            .getNumDaysInMonth() - 1);

    // Add dates of first week from previous month
    int weekdayOfFirstDate = firstDateOfMonth.getWeekDay();

    // If weekdayOfFirstDate smaller than startDayOfWeek
    // For e.g: weekdayFirstDate is Monday, startDayOfWeek is Tuesday
    // increase the weekday of FirstDate because it's in the future
    if (weekdayOfFirstDate < startDayOfWeek) {
        weekdayOfFirstDate += 7;
    }

    while (weekdayOfFirstDate > 0) {
        DateTime dateTime = firstDateOfMonth.minusDays(weekdayOfFirstDate
                - startDayOfWeek);
        if (!dateTime.lt(firstDateOfMonth)) {
            break;
        }

        datetimeList.add(dateTime);
        weekdayOfFirstDate--;
    }

    // Add dates of current month
    for (int i = 0; i < lastDateOfMonth.getDay(); i++) {
        datetimeList.add(firstDateOfMonth.plusDays(i));
    }

    // Add dates of last week from next month
    int endDayOfWeek = startDayOfWeek - 1;

    if (endDayOfWeek == 0) {
        endDayOfWeek = 7;
    }

    if (lastDateOfMonth.getWeekDay() != endDayOfWeek) {
        int i = 1;
        while (true) {
            DateTime nextDay = lastDateOfMonth.plusDays(i);
            datetimeList.add(nextDay);
            i++;
            if (nextDay.getWeekDay() == endDayOfWeek) {
                break;
            }
        }
    }

    // Add more weeks to fill remaining rows
    if (sixWeeksInCalendar) {
        int size = datetimeList.size();
        int row = size / 7;
        int numOfDays = (6 - row) * 7;
        DateTime lastDateTime = datetimeList.get(size - 1);
        for (int i = 1; i <= numOfDays; i++) {
            DateTime nextDateTime = lastDateTime.plusDays(i);
            datetimeList.add(nextDateTime);
        }
    }

    return datetimeList;
}

Then in getView of adapter you have a textview

textView.setText("" + dateTime.getDay());

Coloring dates is setting a background for the textview (for dates which has events).

Right now events are fetched once. Based on starttime which is in milliseconds we get the date from calendar and color the specific dates accordingly.

I am looking for a better way to map events to dates. I am not sure if the right code fragments have been posted. Do let me know if anything is needed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.