This library allows you to create a completely customizable calendar.
You can use CustomizableCalendar
to create your calendar, customizing UI and behaviour.
- Custom header (should be implemented by the user);
- Custom sub view (month name by default);
- Custom weekly days view;
- Custom date view;
- Possibility to implement selection on day click;
- Possibility to implement weekly day calculation;
- Receive updates of Calendar (with AUCalendar);
- Every change to AUCalendar is notified and automatically refreshes UI;
- Only portrait orientation is supported
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
compile 'com.github.MOLO17:CustomizableCalendar:v0.1.2'
}
- RecyclerView
- Joda-Time
- ButterKnife
- RxJava2
- Retrolambda
Add CustomizableCalendar to your layout
<com.molo17.customizablecalendar.library.components.CustomizableCalendar
android:id="@+id/customizable_calendar"
android:layout_width="match_parent"
android:layout_height="wrap_content />
First of all you should create a class that implements ViewInteractor
interface (you can find the explanation in the How to customize > Java
section).
After that go in the Activity/Fragment where you added the CustomizableCalendar
View;
here you should specify the first month and the last month, to do this, create a Calendar
(located in com.molo17.customizablecalendar.library.model
) object.
An example of CustomizableCalendar
init is the following:
...
@BindView(R.id.customizable_calendar)
CustomizableCalendar customizableCalendar;
private CompositeDisposable subscriptions;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
DateTime today = new DateTime();
// setting up first and last month that must be showed in the calendar
DateTime firstMonth = today.withDayOfMonth(1);
DateTime lastMonth = today.plusMonths(3).withDayOfMonth(1);
// create the Calendar obj and setting it up with some configs like:
// - first selected day
// - last selected day
// - multiple selection
final Calendar calendar = new Calendar(firstMonth, lastMonth);
calendar.setFirstSelectedDay(today.plusDays(4));
// if you don't want the multiple selection mode just skip the 2 lines below
calendar.setLastSelectedDay(today.plusDays(6));
calendar.setMultipleSelection(true);
// create a ViewInteractor obj needed to interact with the CustomizableCalendar
final YourViewInteractorClass calendarViewInteractor = new YourViewInteractorClass();
// create an AUCalendar object (a Calendar wrapper that operates as a singleton and provides all the updates)
AUCalendar auCalendar = AUCalendar.getInstance(calendar);
// this is needed to receives all Calendar updates (using RxJava 2)
subscriptions.add(
auCalendar.observeChangesOnCalendar().subscribe(new Consumer<AUCalendar.ChangeSet>() {
@Override
public void accept(AUCalendar.ChangeSet changeSet) throws Exception {
// with ChangeSet you can be aware of which Calendar fields are changed
// you can use changeSet.isFieldChanged(...) passing the name of the field;
// name of the fields can be retrieved using CalendarFields interface;
// AUCalendar is already updated because it's a singleton,
// so for retrieving the updated data you can just use AUCalendar getters
}
})
);
// injecting the ViewInteractor to the CustomizableCalendar View
customizableCalendar.injectViewInteractor(calendarViewInteractor)
}
@Override
protected void onDestroy() {
super.onDestroy();
subscriptions.clear();
}
...
If you want to customize the components you should create a separeted layout and add the reference to the customizable_calendar
View with the tag app:layout="@layout/your_layout"
An example of a custom layout is the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="30dp"
android:layout_marginStart="30dp"
android:orientation="vertical">
<com.molo17.customizablecalendar.library.components.HeaderView
android:id="@android:id/primary"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.molo17.customizablecalendar.library.components.SubView
android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp" />
<com.molo17.customizablecalendar.library.components.WeekDaysView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp" />
<com.molo17.customizablecalendar.library.components.CalendarRecyclerView
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="@dimen/customizable_calendar_height"
android:layout_marginTop="15dp" />
</LinearLayout>
NOTE that ids must not be different from the ones above, so:
@android:id/primary
for HeaderView;@android:id/text1
for WeekDaysView;@android:id/text2
for SubView;@android:id/content
for CalendarRecyclerView;
First (red) rectangle of the screenshot above.
It's a RelativeLayout
, you should create your own layout.
Third (light blue) rectangle of the screenshot above.
It's a RecyclerView
, the ViewHolder item is already implemented.
You can create your own ViewHolder layout using a RelativeLayout
with a TextView
that has @android:id/summary
as id.
Second (green) rectangle of the screenshot above.
It's a RelativeLayout
, implemented by default with the name of the month centered.
If you want to create your own layout make sure to have a TextView
with id @android:id/summary
.
Fourth (blue) rectangle of the screenshot above.
It's a RelativeLayout
, implemented by default with a LinearLayout
(with a GridLayout
inside) for the month and a RelativeLayout
for the day.
If you want to create your own month layout you can specify app:month_layout="@layout/your_layout"
for the month and app:cell_layout="@layout/your_layout"
for the day.
Make sure to use @android:id/widget_frame
as id for the GridView
and @android:id/background
, @android:id/startSelectingText
, @android:id/stopSelectingText
, @android:id/title
respectively for single selection background, first day selection background (in multiple selection mode), last day selection background (in multiple selection mode) and the TextView
where the day is displayed.
All code customization can be applied using the ViewInteractor
.
Here are listed all of the methods with a small description:
-
void onCustomizableCalendarBindView(View view)
Here you can customize theCustomizableCalendar
View.
This method is called aftercustomizableCalendar.injectViewInteractor(...)
. -
void onHeaderBindView(ViewGroup view)
Here you can customize theHeaderView
View, inflating your layout etc...
This method is called afterheaderView.injectViewInteractor(...)
. -
void onWeekDaysBindView(View view)
Here you can customize theWeekDays
View.
This method is called afterweekDays.injectViewInteractor(...)
. -
void onWeekDayBindView(WeekDaysViewAdapter.WeekDayVH holder, String weekDay)
Here you can customize theWeekDayVH
ViewHolder.
This method is called afteronBindViewHolder
ofWeekDaysViewAdapter
. -
void onSubViewBindView(View view, String month)
Here you can customize theSubView
View.
This method is called afteronMonthChanged
. -
void onCalendarBindView(View view)
Here you can customize theCalendarRecyclerView
View.
This method is called aftercalendarRecyclerView.injectViewInteractor(...)
. -
void onMonthBindView(View view)
Here you can customize theMonthGridView
View.
This method is called afteronCreateViewHolder
ofCalendarViewAdapter
. -
View onMonthCellBindView(View view, CalendarItem currentItem)
Here you can customize theGridViewCell
View.
This method is called in thegetView
ofMonthAdapter
, you must return the customized view. -
boolean hasImplementedMonthCellBinding()
Here you should returntrue
if you have implemented the above method (onMonthCellBindView
).
This method is called in thegetView
method ofMonthAdapter
. -
List<CalendarItem> calculateDays(int year, int month, int firstDayOfMonth, int lastDayOfMonth)
Here you can calculate the days of the month (if you want for example to includeSaturday
andSunday
)
This method is called in thegetView
ofMonthAdapter
. -
boolean hasImplementedDayCalculation()
Here you should returntrue
if you have implemented the above method (calculateDays
).
This method is called in therefreshDays
method ofMonthAdapter
. -
int setSelected(boolean multipleSelection, DateTime dateSelected)
Here you can calculate the selection of the day.
This method is called in thesetSelected
method ofMonthAdapter
.
You must return 0, 1 or -1 respectively forfirst selection
,last selection
andno selection
. -
boolean hasImplementedSelection()
Here you should returntrue
if you have implemented the above method (setSelected
).
This method is called in thesetSelected
method ofMonthAdapter
. -
String formatWeekDayName(String nameOfDay);
Here you can format the name of the week day.
This method is called afterinjectViewInteractor
method ofWeekDaysView
.
You should return the formatted name of the week day. -
boolean hasImplementedWeekDayNameFormat()
Here you should returntrue
if you have implemented the above method (formatWeekDayName
).
This method is called afterinjectViewInteractor
method ofWeekDaysView
. -
View getMonthGridView(View rootView)
Here you can create your customizedMonthGridView
.
You should return aMonthGridView
.
This method is called in theonCreateViewHolder
method ofCalendarViewAdapter
.
To report a specific problem or feature request, open a new issue here on Github. For questions, suggestions, or anything else, email us at [email protected].