A better calendar for Android

Related tags

Date & Time Caldroid
Overview

Caldroid

Caldroid is a fragment that display calendar with dates in a month. Caldroid can be used as embedded fragment, or as dialog fragment. User can also swipe left/right to navigate to different months.

It's very easy to customize look and feel of Caldroid using your own theme, thanks to @crocodile2u contribution. There are two default themes in Caldroid (Light and Dark). You can provide your own theme based on these default themes as well.

Caldroid is fully localized. You can customize start day of the week for different countries. By default calendar start on Sunday.

Caldroid can be used with Android 2.2 and above. It is extracted from official Roomorama application

If you found bugs specific to Caldroid, please open a new issue on Github. However for general Android questions (about layout, drawable, etc), you probably can find more information on StackOverflow.

Setup

For Android Studio user: add compile 'com.roomorama:caldroid:3.0.1' to your gradle build file.

For Maven user:

<dependency>
    <groupId>com.roomorama</groupId>
    <artifactId>caldroid</artifactId>
    <version>3.0.1</version>
</dependency>

For Eclipse/ADT user: please see tag eclipse_project, download the source codes, check out the CaldroidSample to see how the library works. However you are strongly recommended to use Maven or gradle, because this tag is no longer supported.

To use in your project, reference the child library project as a library. If you see JAR mismatched error, replace your android-support-v4.jar to the jar inside Caldroid. Make sure you compile the project against Android 4.2 and above to allow nested fragment. See more at http://developer.android.com/about/versions/android-4.2.html#NestedFragments

Features

##Flexible setup: can be embedded or shown as dialog If you support Android 2.2 and above, you can embed caldroid fragment in your activity with below code:

CaldroidFragment caldroidFragment = new CaldroidFragment();
Bundle args = new Bundle();
Calendar cal = Calendar.getInstance();
args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
caldroidFragment.setArguments(args);

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.calendar1, caldroidFragment);
t.commit();

If your app only target minSdkVersion 16 and above, you can use Caldroid too. First, you need to change your Activity class to FragmentActivity, and add support library to your project. You don't have to change how you use android.app.Fragment.

CaldroidFragment caldroidFragment = new CaldroidFragment();
Bundle args = new Bundle();
Calendar cal = Calendar.getInstance();
args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
caldroidFragment.setArguments(args);

android.support.v4.app.FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.cal, caldroidFragment);
t.commit();

You can also embed caldroid fragment as a child in your fragment.

Caldroid accepts numerous arguments during start up:

public final static String
            DIALOG_TITLE = "dialogTitle",
            MONTH = "month",
            YEAR = "year",
            SHOW_NAVIGATION_ARROWS = "showNavigationArrows",
            DISABLE_DATES = "disableDates",
            SELECTED_DATES = "selectedDates",
            MIN_DATE = "minDate",
            MAX_DATE = "maxDate",
            ENABLE_SWIPE = "enableSwipe",
            START_DAY_OF_WEEK = "startDayOfWeek",
            SIX_WEEKS_IN_CALENDAR = "sixWeeksInCalendar",
            ENABLE_CLICK_ON_DISABLED_DATES = "enableClickOnDisabledDates",
            SQUARE_TEXT_VIEW_CELL = "squareTextViewCell",
            THEME_RESOURCE = "themeResource";

To customize the startDayOfWeek, just use

Bundle args = new Bundle();
args.putInt(CaldroidFragment.START_DAY_OF_WEEK, CaldroidFragment.TUESDAY); // Tuesday
caldroidFragment.setArguments(args);

If you want to know when user clicks on disabled dates:

Bundle args = new Bundle();
args.putBoolean(CaldroidFragment.ENABLE_CLICK_ON_DISABLED_DATES, true);
caldroidFragment.setArguments(args);

By default, Caldroid use square TextView to display date. However when the screen has limited space, user can switch to normal TextView instead:

Bundle args = new Bundle();
args.putBoolean(CaldroidFragment.SQUARE_TEXT_VIEW_CELL, false);
caldroidFragment.setArguments(args);

Caldroid uses SQUARE_TEXT_VIEW_CELL parameter internally as well. When the phone is in portrait mode, it will default SQUARE_TEXT_VIEW_CELL to true, and on landscape, SQUARE_TEXT_VIEW_CELL is set to false. If your app provides different value, Caldroid will use your value instead of the default one.

To show the caldroid fragment as a dialog, you might want to set the dialog title. There is a convenient method for that:

CaldroidFragment dialogCaldroidFragment = CaldroidFragment.newInstance("Select a date", 3, 2013);
dialogCaldroidFragment.show(getSupportFragmentManager(),"TAG");

Custom theme

You can define your own theme to change the look and feel of Caldroid without having to subclass it. You should inherit from base theme CaldroidDefault. Here's how to create a dark theme:

    <!-- Dark theme. -->
    <style name="CaldroidDefaultDark" parent="CaldroidDefault">
        <item name="styleCaldroidViewLayout">@style/CaldroidDefaultDarkCalendarViewLayout</item>
        <item name="styleCaldroidMonthName">@style/CaldroidDefaultDarkMonthName</item>
        <item name="styleCaldroidNormalCell">@style/CaldroidDefaultDarkNormalCell</item>
        <item name="styleCaldroidSquareCell">@style/CaldroidDefaultDarkSquareCell</item>
        <item name="styleCaldroidGridView">@style/CaldroidDefaultDarkGridView</item>
    </style>

    <style name="CaldroidDefaultDarkCalendarViewLayout">
        <item name="android:background">@android:color/black</item>
    </style>

    <style name="CaldroidDefaultDarkMonthName" parent="CaldroidDefaultMonthName">
        <item name="android:textColor">@color/caldroid_white</item>
    </style>

    <style name="CaldroidDefaultDarkGridView" parent="CaldroidDefaultGridView">
        <item name="android:background">@color/caldroid_middle_gray</item>
    </style>

    <style name="CaldroidDefaultDarkCell" parent="CaldroidDefaultCell">
        <item name="android:textColor">@color/cell_text_color_dark</item>
        <item name="android:background">@drawable/cell_bg_dark</item>
    </style>

    <style name="CaldroidDefaultDarkNormalCell" parent="CaldroidDefaultDarkCell">
        <item name="android:padding">5dp</item>
    </style>

    <style name="CaldroidDefaultDarkSquareCell" parent="CaldroidDefaultDarkCell" />

After creating your own theme, supply it to your Caldroid fragment:

Bundle args = new Bundle();
args.putInt(CaldroidFragment.THEME_RESOURCE, com.caldroid.R.style.CaldroidDefaultDark);
caldroidFragment.setArguments(args);

Custom backgrounds and text colors for different dates

It is very easy to supply different backgrounds and text colors for different dates:

// You can use any of below methods to set background colors
public void setBackgroundDrawableForDates(HashMap<Date, Drawable> backgroundForDateMap);
public void setBackgroundDrawableForDateTimes(HashMap<DateTime, Drawable> backgroundForDateTimeMap);
public void setBackgroundDrawableForDate(Drawable drawable, Date date);
public void setBackgroundDrawableForDateTime(Drawable drawable, DateTime dateTime);

// Below methods is to set text color
public void setTextColorForDates(HashMap<Date, Integer> textColorForDateMap);
public void setTextColorForDateTimes(HashMap<DateTime, Integer> textColorForDateTimeMap);
public void setTextColorForDate(int textColorRes, Date date);
public void setTextColorForDateTime(int textColorRes, DateTime dateTime);

To use these methods, you can define your colors in color.xml and background in drawable folder:

ColorDrawable blue = new ColorDrawable(getResources().getColor(R.color.blue));
ColorDrawable green = new ColorDrawable(Color.GREEN);
caldroidFragment.setBackgroundDrawableForDate(blue, blueDate);
caldroidFragment.setBackgroundDrawableForDate(green, greenDate);

caldroidFragment.setTextColorForDate(R.color.white, blueDate);
caldroidFragment.setTextColorForDate(R.color.white, greenDate);

You need to call refreshView() after above methods to update calendar appearance.

You can also clear the background and text color:

public void clearBackgroundDrawableForDate(Date date);
public void clearBackgroundDrawableForDates(List<Date> dates);
public void clearTextColorForDates(List<Date> dates);
public void clearTextColorForDate(Date date);

Display user events on Caldroid

Caldroid is simply an UI library and it does not connect to user calendar database or fetch any user's events. If your app wants to display these events on Caldroid:

  • Your app needs to fetch events (from server or from user calendar database, depend on your app)

  • Design a drawable for the date with event. See more here for all types of drawable you can create: http://developer.android.com/guide/topics/resources/drawable-resource.html

  • Use above setBackgroundDrawableForDate method to set the event drawable to correct date

  • Call refreshView() to update calendar appearance

If you need to customize more for the cell, you can supply your own cell design.

Set min / max date

Client can use below methods:

public void setMinDate(Date minDate);
public void setMinDateFromString(String minDateString, String dateFormat);

public void setMaxDate(Date minDate);
public void setMaxDateFromString(String maxDateString, String dateFormat);

To refresh the calendar, just call refreshView()

Set disabled dates

Client can either provide ArrayList or ArrayList to Caldroid.

public void setDisableDates(ArrayList<Date> disableDateList);
public void setDisableDatesFromString(ArrayList<String> disableDateStrings);
public void setDisableDatesFromString(ArrayList<String> disableDateStrings, String dateFormat);

To clear the disabled dates:

public void clearDisableDates();

##Select dates within a range To select dates within a range:

public void setSelectedDates(Date fromDate, Date toDate);
public void setSelectedDateStrings(String fromDateString, String toDateString, String dateFormat);

To clear the selected dates:

public void clearSelectedDates();

##Show / Hide the navigation arrows to move to previous or next month To show/hide the navigation arrows:

public void setShowNavigationArrows(boolean showNavigationArrows);

To enable / disable swipe:

public void setEnableSwipe(boolean enableSwipe);

Client can programmatically move the calendar (with animation) to a specified date:

public void moveToDate(Date date);
public void moveToDateTime(DateTime dateTime);

##Allow user to select a date and inform listener

Caldroid inform clients via CaldroidListener.

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) {
		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();
	}

};

caldroidFragment.setCaldroidListener(listener);

User can also customize the navigation arrows and month title textView: font, size, onClickListener, onLongClickListener, etc. Client can supply different adapter to the weekdayGridView. Make sure you only access these methods after Caldroid has been successfully attached to view, otherwise you will see NullPointerException.

final CaldroidListener listener = new CaldroidListener() {

    @Override
    public void onSelectDate(Date date, View view) {
        // Do something
    }

    @Override
    public void onCaldroidViewCreated() {
        // Supply your own adapter to weekdayGridView (SUN, MON, etc)
        caldroidFragment.getWeekdayGridView().setAdapter(YOUR_ADAPTER);

        Button leftButton = caldroidFragment.getLeftArrowButton();
        Button rightButton = caldroidFragment.getRightArrowButton();
        TextView textView = caldroidFragment.getMonthTitleTextView();

        // Do customization here
    }

};

caldroidFragment.setCaldroidListener(listener);

##Handle screen rotation

To handle rotation properly, Caldroid provides method to get current states of the fragment:

public Bundle getSavedStates();
public void saveStatesToKey(Bundle outState, String key);
public void restoreStatesFromKey(Bundle savedInstanceState, String key);
public void restoreDialogStatesFromKey(FragmentManager manager, Bundle savedInstanceState, String key, String dialogTag)

Using above method, you can save current state of Caldroid on onSaveInstanceState(Bundle outState) method.

On your activity code:

@Override
protected void onSaveInstanceState(Bundle outState) {
	// TODO Auto-generated method stub
	super.onSaveInstanceState(outState);

	if (caldroidFragment != null) {
		caldroidFragment.saveStatesToKey(outState, "CALDROID_SAVED_STATE");
	}

	if (dialogCaldroidFragment != null) {
		dialogCaldroidFragment.saveStatesToKey(outState,
				"DIALOG_CALDROID_SAVED_STATE");
	}
}

Then you can restore the state in onCreate(Bundle savedInstanceState) of your activity. The algorithm is like below:

// If Activity is created after rotation
if (savedInstanceState != null) {
  caldroidFragment.restoreStatesFromKey(savedInstanceState,
					"CALDROID_SAVED_STATE");
}

// If activity is created from fresh
else {
  Bundle args = new Bundle();
	Calendar cal = Calendar.getInstance();
  args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
  args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
  args.putBoolean(CaldroidFragment.ENABLE_SWIPE, true);
  args.putBoolean(CaldroidFragment.SIX_WEEKS_IN_CALENDAR, false);
  caldroidFragment.setArguments(args);
}

If you use Caldroid as dialog, you can use restoreDialogStatesFromKey

final String dialogTag = "CALDROID_DIALOG_FRAGMENT";
if (savedInstanceState != null) {
  dialogCaldroidFragment.restoreDialogStatesFromKey(getSupportFragmentManager(),
      					savedInstanceState, "DIALOG_CALDROID_SAVED_STATE",
      					dialogTag);
	Bundle args = dialogCaldroidFragment.getArguments();
	args.putString("dialogTitle", "Select a date");
} else {
	// Setup arguments
	Bundle bundle = new Bundle();
	// Setup dialogTitle
	bundle.putString(CaldroidFragment.DIALOG_TITLE, "Select a date");
	dialogCaldroidFragment.setArguments(bundle);
}

Refer to the CaldroidSampleActivity for more detail.

##Allow customized cell for the dates gridView

Caldroid provides flexible API to supply your own cell view. What you have to do is:

  1. Create your own cell view layout in your project

  2. Subclass CaldroidGridAdapter and override getView(int position, View convertView, ViewGroup parent). See CaldroidSampleCustomAdapter.java for more detail. Here you can customize everything: layout, text color, background for different states (normal, disable, selected)

  3. Subclass CaldroidFragment to use your custom adapter instead of the default CaldroidGridAdapter. This is simplest step:

public class CaldroidSampleCustomFragment extends CaldroidFragment {

	@Override
	public CaldroidGridAdapter getNewDatesGridAdapter(int month, int year) {
		// TODO Auto-generated method stub
		return new CaldroidSampleCustomAdapter(getActivity(), month, year, getCaldroidData(), extraData);
	}

}
  1. Use your new customized fragment in your project instead of the default CaldroidFragment.

To see how it works, you can uncomment this line in CaldroidSampleActivity

// final CaldroidSampleCustomFragment caldroidFragment = new CaldroidSampleCustomFragment();

The extraData is a HashMap<String, Object>, is designed to let client injects custom data to CaldroidGridAdapter, so that data can be used to customize the date grid view. Usage is simple:

In your client code:

// To set the extraData:
HashMap<String, Object> extraData = caldroidFragment.getExtraData();
extraData.put("YOUR_CUSTOM_DATA_KEY1", yourCustomData1);
extraData.put("YOUR_CUSTOM_DATA_KEY2", yourCustomData2);

// Refresh view
caldroidFragment.refreshView();

In the CaldroidSampleCustomAdapter:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  // Get your data here
  ArrayList yourCustomData1 = (ArrayList) extraData.get("YOUR_CUSTOM_DATA_KEY1");
  String yourCustomData2 = (String) extraData.get("YOUR_CUSTOM_DATA_KEY2");

  // Continue to build your customized view
}

Basic Structure

Caldroid fragment includes 4 main parts:

  1. Month title view: show the month and year (e.g MARCH, 2013)

  2. Navigation arrows: to navigate to next month or previous month

  3. Weekday gridview: contains only 1 row and 7 columns. To display "SUN, MON, TUE, WED, THU, FRI, SAT"

  4. An infinite view pager that allow user to swipe left/right to change month. This library is taken from https://github.com/antonyt/InfiniteViewPager

This infinite view pager recycles 4 fragment, each fragment contains a gridview with 7 columns to display the dates in month. Whenever user swipes different screen, the date grid views are updated.

Others

Caldroid code is simple and clean partly because of powerful date4j library!

License

See LICENSE.md

App uses Caldroid

SilentMe

Work Mate

Attendance Register (students)

eDiary

Moon Calendar

Bitdeli Badge

Comments
  • Personnalize each cell

    Personnalize each cell

    I'm building a a calendar with 3 kinds of cell, normal cells, cells with price and cells with amount in percentage (see the picture).

    I added an ArrayList of my cells, order by date in the Adapter.

    It's working fine for the selected month, but when i change the month the method getNewDatesGridAdapter is called and i can't figure how to use my array to build the display.

    Do you think there is a better way to do this? device-2013-04-16-100637

    enhancement 
    opened by ben-j69 26
  • Android Studio

    Android Studio

    I'd like to add Caldroid in my project. I'm currently using android studio as IDE, and I can't find the right way to import the library. What should I do?

    opened by ziggy42 22
  • Cannot be nested within a fragment

    Cannot be nested within a fragment

    Given I add the CaldroidFragment into an existing fragment, I will receive this error message:

    java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
    

    This is how I set things up:

    @EFragment(R.layout.frg_analysis)
    public class AnalysisFragment extends SherlockFragment {
    
        @AfterViews
        protected void setupView() {
            CaldroidFragment caldroidFragment = new CaldroidFragment();
            Bundle args = new Bundle();
            Calendar cal = Calendar.getInstance();
            args.putInt("month", cal.get(Calendar.MONTH) + 1);
            args.putInt("year", cal.get(Calendar.YEAR));
            caldroidFragment.setArguments(args);
    
            FragmentTransaction t = getChildFragmentManager().beginTransaction();
            t.add(R.id.containerCalendar, caldroidFragment);
            t.commit();
        }
    }
    

    Stackoverflow has some hints: http://stackoverflow.com/questions/14850573/cant-retain-nested-fragments .

    Full stacktrace:

    E/AndroidRuntime( 1763): java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
    E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.setRetainInstance(Fragment.java:742)
    E/AndroidRuntime( 1763):    at com.caldroid.CaldroidFragment.onCreate(CaldroidFragment.java:924)
    E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.performCreate(Fragment.java:1437)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:877)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
    E/AndroidRuntime( 1763):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
    E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.performStart(Fragment.java:1481)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:941)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
    E/AndroidRuntime( 1763):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
    E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
    E/AndroidRuntime( 1763):    at android.os.Handler.handleCallback(Handler.java:725)
    E/AndroidRuntime( 1763):    at android.os.Handler.dispatchMessage(Handler.java:92)
    E/AndroidRuntime( 1763):    at android.os.Looper.loop(Looper.java:137)
    E/AndroidRuntime( 1763):    at android.app.ActivityThread.main(ActivityThread.java:5041)
    E/AndroidRuntime( 1763):    at java.lang.reflect.Method.invokeNative(Native Method)
    E/AndroidRuntime( 1763):    at java.lang.reflect.Method.invoke(Method.java:511)
    E/AndroidRuntime( 1763):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    E/AndroidRuntime( 1763):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    E/AndroidRuntime( 1763):    at dalvik.system.NativeStart.main(Native Method)
    
    opened by ened 19
  • using the library

    using the library

    I would like to use this calendar view in my app. I am new to android and this is my first app.

    I tried importing this to library folder, copied the file contents into my project, searched for jar. After searching on how to reference library projects, I found this one http://www.vogella.com/tutorials/AndroidLibraryProjects/article.html and tried to do the same.. So I tried to create a project with the files supplied in the library folder I get error

    import com.caldroid.R; - The import com.caldroid.R cannot be resolved

    When I tried to use the sample demo I was getting the same error...

    import com.roomorama.caldroid.CaldroidFragment; - The import com.roomorama cannot be resolved import com.roomorama.caldroid.CaldroidListener; - The import com.roomorama cannot be resolved

    Please help me.. Very sorry if my question is stupid. I am new and this is the first time I am trying to use a library.

    opened by balasivagnanam 18
  • Month title missing

    Month title missing

    default Thanks for sharing this wonderful work. I'm just starting to use caldroid and my month title is missing. I can't figure out why. The grey rectangle in the upper-left hand corner seems to be "next month" arrow because it change to next month when I click it. Any idea on how this is happening?

    opened by DavidH46 15
  • Themable caldriod?

    Themable caldriod?

    Hello. At the moment, as I see it, caldroid colors are referenced in the XML layouts as android:background="@color/color_name" This makes it difficult to apply custom themes. What if you referenced colors like this: android:background="?colorName". colorName attribute would be available in attrs.xml, and in caldroid default theme there would be an entry: @color/color_name

    This way, user will be able to call caldroidFragment.setStyle() in order to change calendar appearance to their own. Drawables used for buttons etc could also be made customizable that way.

    opened by crocodile2u 15
  • Incorrect Caldroid fragment height in ScrollView

    Incorrect Caldroid fragment height in ScrollView

    Hi,

    Tried to reproduce Roomorama's nice Availability page, with multiple, scrollable Caldroid fragments: https://www.dropbox.com/s/0kpb8435ffv1psp/Screenshot_2013-08-26-18-17-53.png

    If I add multiple Caldroid fragments to a LinearLayout that's fine, no problem at all. BUT if I embed it into a ScrollView, height will be messed, and I'll get this: https://www.dropbox.com/s/g3ntnkrnr8shbbv/Screenshot_2013-08-26-17-57-54.png

    Please let me know if you have any idea, or workaround.

    Thank you!

    question 
    opened by gabororosz 13
  • Event on day from database

    Event on day from database

          final CaldroidListener listener = new CaldroidListener() {
    
            @Override
            public void onSelectDate(Date date, View view) {
            }
    
            @Override
            public void onChangeMonth(int month, int year) {
    
                String text = "month: " + month + " year: " + year;
                String monthS = String.valueOf(month);
                String yearS = String.valueOf(year);
    
                String[] args = { monthS , yearS }; 
                c= CaldroidSampleActivity.this.getContentResolver().query(CalendarProvider.CONTENT_URI,
                        new String[] {CalendarProvider.ID,CalendarProvider.EVENT,
                        CalendarProvider.DESCRIPTION,CalendarProvider.LOCATION,
                        CalendarProvider.YEAR,CalendarProvider.MONTH,CalendarProvider.DAY,
                        CalendarProvider.HOURS,CalendarProvider.MINUTES},"month=? and year=?",args, null);
                new GetEvents().execute();
    
            }
    
            @Override
            public void onLongClickDate(Date date, View view) {
            }
    
            @Override
            public void onCaldroidViewCreated() {
                if (caldroidFragment.getLeftArrowButton() != null) {
    
                }
            }
    
        };
    

    In AsyncTask i fetch the events from ContentProvider based on month and the year.

       private class GetEvents extends AsyncTask<Void,Void,ArrayList<Event>>{
    
        @Override
        protected ArrayList<Event> doInBackground(Void... params) {
            events.clear();
    
    
    
            if( c.moveToFirst()){
                do{
                    Event event = new Event();
    
                            event.setEVENT(c.getString(c.getColumnIndex(CalendarProvider.EVENT)));
                            event.setLOCATION(c.getString(c.getColumnIndex(CalendarProvider.LOCATION)));
                            event.setDESCRIPTION(c.getString(c.getColumnIndex(CalendarProvider.DESCRIPTION)));  
                            event.setYEAR(c.getString(c.getColumnIndex(CalendarProvider.YEAR)));
    
                            event.setMONTH(c.getString(c.getColumnIndex(CalendarProvider.MONTH)));
                            event.setDAY(c.getString(c.getColumnIndex(CalendarProvider.DAY)));
                            event.setHOURS(c.getString(c.getColumnIndex(CalendarProvider.HOURS)));
                            event.setMINUTES(c.getString(c.getColumnIndex(CalendarProvider.MINUTES)));
                            events.add(event);
                        }while(c.moveToNext()); 
                        c.close();
            }
    
    
    
            return events;
        }
        @Override
        protected void onPostExecute(ArrayList<Event> result){
    
    
            for(int i=0;i<result.size();i++)
            {
    
            int day = Integer.parseInt(result.get(i).getDAY());  //25
            int month = Integer.parseInt(result.get(i).getMONTH()); //12
            int year = Integer.parseInt(result.get(i).getYEAR()); // 1988
    
            Calendar c = Calendar.getInstance();
            c.set(year, month-1, day, 0, 0);  
            Date greenDate = c.getTime();
            ;
    
            if (caldroidFragment != null) {
    
                caldroidFragment.setBackgroundResourceForDate(R.color.blue,greenDate);
    
            }
            }
    
        }
    }
    

    The problem

    After fetching the events form database i set the color to the date.

    Example : On Jan 1 2015 i have a event. So i change the color of the date. But this change is visible once i move to Feb and come back to Jan. I am looking at the source and trying to figure out the issue.

    This issue is not seen if i fetch events from database all at a time which is time consuming. So i would prefer fetching events based on month and year.

    opened by raghunandankavi2010 11
  • [Q] Display events when using customized cell

    [Q] Display events when using customized cell

    @thomasdao Thank you for your very nice lib. I'm using it to display a calendar which has many events for one date. Like this: image

    I already put all events inside a scrollview, but it seems the scrollbar not working.

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:gravity="bottom"
                            android:orientation="horizontal">
                            <ImageView
                                android:id="@+id/iv_duty_type_1"
                                android:layout_width="25dp"
                                android:layout_height="25dp"
                                android:layout_marginRight="5dp"
                                android:layout_marginBottom="2dp"
                                android:padding="3dp"/>
                            <TextView
                                android:id="@+id/tv_event_1"
                                android:textAllCaps="true"
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"/>
                    </LinearLayout>
                    ....
            </LinearLayout>
        </ScrollView>
    

    Could you please support me with this issue?

    opened by DarkMagic 11
  • RunTime Exception

    RunTime Exception

    Dear Team

    after updating android studio APIs i got this exception 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: Caused by: java.lang.RuntimeException: Binary XML file line #13: You must supply a layout_width attribute. 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:492) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:6056) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.ViewGroup$MarginLayoutParams.(ViewGroup.java:6225) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.widget.RelativeLayout$LayoutParams.(RelativeLayout.java:1246) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:1083) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:84) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:768) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:769) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:498) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:398) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at com.roomorama.caldroid.CaldroidFragment.onCreateView(CaldroidFragment.java:1241) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1188) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.Activity.performStart(Activity.java:5382) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2266) 10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.ActivityThread.access$700(ActivityThread.java:159)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.os.Looper.loop(Looper.java:176)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5419)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:525)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)  10-07 00:08:57.194 4168-4168/vc.baakline E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)

    i read about this exception missing attributes for views in this case layout_width and layout_height is missing Thank you in advance

    opened by kun-hadi 10
  • Limit the scroll

    Limit the scroll

    How can I limit the scroll with setMinDate and setMaxDate?

    This functions does only deactive the dates but I want to user can't scroll more than min max dates.

    opened by birfincankafein 9
  • API 29 / AndroidX FragmentManager.isDestroyed() crash

    API 29 / AndroidX FragmentManager.isDestroyed() crash

    Hello,

    I'm getting a crash on API 29 when the androidx fragment is destroyed by android.

    This SO question suggests removing the deallocation via reflection in CaldroidFragment.onDetach:

    https://stackoverflow.com/questions/56925777/boolean-androidx-fragment-app-fragmentmanagerimpl-isdestroyed-on-a-null-obje

    Removing the onDetach() method fixes the crash for me. Should maybe check if API < 29 before deallocating via reflection?

    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.fragment.app.FragmentManager.isDestroyed()' on a null object reference
            at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4687)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4705)
            at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39)
            at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:214)
            at android.app.ActivityThread.main(ActivityThread.java:6986)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.fragment.app.FragmentManager.isDestroyed()' on a null object reference
            at androidx.fragment.app.Fragment.performDetach(Fragment.java:2944)
            at androidx.fragment.app.FragmentStateManager.detach(FragmentStateManager.java:469)
            at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1331)
            at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1398)
            at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1476)
            at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1541)
            at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2858)
            at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:2843)
            at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:330)
            at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:365)
            at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:233)
            at android.app.Activity.performDestroy(Activity.java:7680)
            at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1306)
            at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4672)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4705) 
            at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39) 
            at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926) 
            at android.os.Handler.dispatchMessage(Handler.java:106) 
            at android.os.Looper.loop(Looper.java:214) 
            at android.app.ActivityThread.main(ActivityThread.java:6986) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445) 
    
    opened by btraas 5
  • Calendar nav buttons under material design theme (non androidx)

    Calendar nav buttons under material design theme (non androidx)

    Faced issue with icon-less buttons navigating calendar back and force (happening under material compat theme, specifically Theme.MaterialComponents.Light.NoActionBar descendant). This PR resolves the issue. Sharing just in case someone faces similar situation.

    opened by oradkovsky 0
  • you can add me to

    you can add me to "apps using list"

    I used this awesome library for our app, Thanks for the library.

    Muster Dekho app

    https://play.google.com/store/apps/details?id=com.musterdekho.school

    opened by yashptl31 0
  • Fix crash with androidx appcompat 1.1.0

    Fix crash with androidx appcompat 1.1.0

    This prevents a crash with appcompat 1.1.0.

    Exception thrown:

    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: ***, PID: 5575
        java.lang.RuntimeException: Unable to destroy activity {***/***.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.fragment.app.FragmentManagerImpl.isDestroyed()' on a null object reference
            at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4458)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4476)
            at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:4760)
            at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4693)
            at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
            at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:55)
            at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:4743)
            at android.app.ActivityThread.access$3200(ActivityThread.java:199)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1818)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:6669)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.fragment.app.FragmentManagerImpl.isDestroyed()' on a null object reference
            at androidx.fragment.app.Fragment.performDetach(Fragment.java:2844)
            at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1033)
            at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1237)
            at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1302)
            at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2655)
            at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:2640)
            at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:329)
            at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:366)
            at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:233)
            at ***.MainActivity.onDestroy(MainActivity.kt:376)
            at android.app.Activity.performDestroy(Activity.java:7395)
            at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1306)
            at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4443)
    

    Associated google tracker issue: https://issuetracker.google.com/issues/135764330

    opened by benoitletondor 6
Owner
Roomorama
Roomorama
📅 Minimal Calendar - This calendar library is built with jetpack compose. Easy, simple, and minimal.

?? Minimal Calendar This calendar library is built with jetpack compose. Easy, simple, and minimal. Latest version The stable version of the library i

Minjae Kim 16 Sep 14, 2022
Android library for better Picker DialogFragments

DialogFragments modeled after the AOSP Clock and Calendar apps to improve UX for picking time, date, numbers, and other things.

Code-Troopers 2.7k Dec 29, 2022
Standalone Android widget for picking a single date from a calendar view.

TimesSquare for Android Standalone Android widget for picking a single date from a calendar view. Usage Include CalendarPickerView in your layout XML.

Square 4.4k Dec 20, 2022
An android library which provides a compact calendar view much like the one used in google calenders.

CompactCalendarView CompactCalendarView is a simple calendar view which provides scrolling between months. It's based on Java's Date and Calendar clas

SundeepK 1.5k Jan 7, 2023
Android open source calendar

Etar Calendar Etar (from Arabic: إِيتَار) is an open source material designed calendar made for everyone! Why? Well, I wanted a simple, material desig

null 1.5k Jan 4, 2023
📅 CosmoCalendar is a fully customizable calendar with a wide variety of features and displaying modes.

CosmoCalendar Made by Applikey Solutions Usage Customization Common Selection Current day Navigation buttons Weekend days Connected days Disabled days

Applikey Solutions 1.6k Dec 22, 2022
CustomizableCalendar is a library that allows you to create your calendar, customizing UI and behaviour

CustomizableCalendar This library allows you to create a completely customizable calendar. You can use CustomizableCalendar to create your calendar, c

MOLO17 216 Dec 6, 2022
Demo app for a horizontal schedule(event) calendar

This is a demo project that showcases a horizontally laid out calendar that shows events in a timeline fashion. It is not a library, just a reference implementation for curious developers.

Halil Ozercan 188 Dec 26, 2022
A simple calendar with events, customizable widgets and no ads.

Simple Calendar A simple calendar with events and a customizable widget. A simple calendar with optional CalDAV synchronization. You can easily create

Simple Mobile Tools 3k Jan 4, 2023
Solutions for Muetzilla's Advent Calendar

Solutions for Muetzilla's Advent Calendar Link To the Advents Calendar Content Solutions for Muetzilla's Advent Calendar Content Problem 1 Problem 2 P

Marc Andri Fuchs 1 Mar 23, 2022
Kmpcalendar - A calendar library and views written for kotlin multiplatform

KMPCalendarView Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compo

Anmol Verma 2 Oct 7, 2022
A Jetpack Compose library for handling calendar component rendering.

Compose Calendar Compose Calendar is a composable handling all complexity of rendering calendar component and date selection. Due to flexibility provi

Bogusz Pawłowski 181 Dec 22, 2022
Calendar - A component for compose desktop

日历 一个用于compose-desktop的日历组件。 截图 feature DayPicker的动画 月份选择器错误提示 点击非本月的时间会跳到上个月 to

wwalkingg 1 Feb 7, 2022
Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling.

Android Week View Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling. Fea

Raquib-ul Alam (Kanak) 3.4k Jan 3, 2023
Joda-Time library with Android specialization

Android has built-in date and time handling - why bother with a library? If you've worked with Java's Date and Calendar classes you can probably answer this question yourself, but if not, check out Joda-Time's list of benefits.

Daniel Lew 2.6k Dec 9, 2022
An adaptation of the JSR-310 backport for Android.

ThreeTen Android Backport An adaptation of the JSR-310 backport for Android. Attention: Development on this library is winding down. Please consider s

Jake Wharton 3.5k Dec 11, 2022
Android NTP time library. Get the true current time impervious to device clock time changes

TrueTime for Android Make sure to check out our counterpart too: TrueTime, an NTP library for Swift. NTP client for Android. Calculate the date and ti

Instacart 1.3k Jan 4, 2023
A material-styled android view that provisions picking of a date, time & recurrence option, all from a single user-interface.

SublimePicker A customizable view that provisions picking of a date, time & recurrence option, all from a single user-interface. You can also view 'Su

Vikram 2.3k Jan 4, 2023
Pick a date or time on Android in style

Material DateTime Picker - Select a time/date in style Material DateTime Picker tries to offer you the date and time pickers as shown in the Material

null 4.7k Dec 29, 2022