diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 0d224931..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-language: android
-
-jdk:
- - oraclejdk8
-
-android:
- components:
- - tools
- - platform-tools
- - build-tools-28.0.3
- - android-28
- - extra-android-m2repository
- - extra-google-m2repository
-
-script:
- - ./gradlew clean check assemble -Dpre-dex=false
-
-notifications:
- email: false
-
-sudo: false
-
-cache:
- directories:
- - $HOME/.gradle
\ No newline at end of file
diff --git a/docs/CUSTOMIZATION.md b/docs/CUSTOMIZATION.md
deleted file mode 100644
index 04451650..00000000
--- a/docs/CUSTOMIZATION.md
+++ /dev/null
@@ -1,134 +0,0 @@
-Customization Options
-=====================
-
-```xml
-
-```
-
-## Tile Size
-
-One of the fundamental concepts in this library is that of `tileSize`.
-Even if you don't set one explicitly, one is calculated and is used in sizing the view.
-
-By default, with no tile size set, the view will scale to fill as much space as it can.
-The functionality is similar to ImageView with `adjustViewBounds` set to true.
-
-If a tileSize is set, that will override the `layout_width` and `layout_height` set.
-
-The view is 7 tiles wide and 8 tiles high (with the top bar visible).
-
-### Width and Height
-
-You also have the possibility to use `tileWidth` and `tileHeight` separately. I would recommend using either `tileSize` or, `tileWidth` and `tileHeight`.
-
-
-## Date Selection
-
-We support four modes of selection: single, multiple, range or none. The default is single selection.
-The mode can be changed by calling `setSelectionMode()` and passing the appropriate constant (`SELECTION_MODE_NONE`, `SELECTION_MODE_SINGLE`, `SELECTION_MODE_RANGE` or `SELECTION_MODE_MULTIPLE`).
-If you change to single selection, all selected days except the last selected will be cleared.
-If you change to none or range, all selected days will be cleared.
-
-You can set an `OnDateSelectedListener` to listen for selections, make sure to take into account multiple calls for the same date and state. In case of range selection, use `OnRangeSelectedListener` which returns the list of date from the range including first and last.
-You can manually select or deselect dates by calling `setDateSelected()`.
-Use `setSelectedDate()` to clear the current selection(s) and select the provided date.
-
-There are also: `clearSelection()`, `getSelectedDates()`, and `getSelectionMode()`; which should work as you would expect.
-
-
-## Showing Other Dates
-
-By default, only days of one month, in the min-max range, are shown.
-You can customize this by setting `mcv_showOtherDates` in xml, or by calling `setShowOtherDates()`.
-
-Avaliable flags are:
-* `other_months`: Show additional days from the previous and next months
- * This flag also enables the `out_of_range` flag, to prevent weird blank areas that nobody wants.
-* `out_of_range`: Show dates that are outside of the minimum and maximum date range
- * This will only affect dates in the current month. Use the `other_months` flag to show other months.
-* `decorated_disabled`: Show dates that are set as disabled by a decorator
- * This will only affect dates in the current month and inside the minimum/maximum date range.
-* `none`: An alias that sets none of the flags
-* `all`: An alias that sets all of the flags
-* `defaults`: An alias of flags set by default. Currently this is only `decorated_disabled`.
-
-There are similar constants on `MaterialCalendarView` such as `MaterialCalendarView.SHOW_DECORATED_DISABLED`.
-
-
-## Selection Color
-
-The default color of the calendar selector is the one set referenced by `?android:attr/colorAccent` on 5.0+ or `?attr/colorAccent` from the AppCompat library (black as a last resort).
-You can provide a custom color by setting `mcv_selectionColor` in xml, or by calling `setSelectionColor()`.
-
-If you want more control than just color, you can use the [decorator api](DECORATORS.md) to set a [custom selector](CUSTOM_SELECTORS.md).
-
-
-## Topbar Options
-
-### Visibility
-
-You can hide or show the topbar (arrow buttons and month label) by calling `setTopbarVisible(boolean)`
-The default is visible.
-
-### Arrows
-
-If you want to change the color or the drawables, they can be set in xml using `mcv_leftArrow` and `mcv_rightArrow` or by calling `setLeftArrow()` and `setRightArrow()`.
-
-## Custom Labels
-
-### Header
-
-You can customize the label displayed in the header by setting a custom `TitleFormatter` by calling `setTitleFormatter()`.
-The formatter's `format()` method will be called with a `CalendarDay` containing the month and year you should format.
-The default implementation uses a `SimpleDateFormat` with a format of `"MMMM yyyy"`.
-The library provides a `DateFormatTitleFormatter` and `MonthArrayTitleFormatter` for convenience.
-
-You can also set a string array resource with `mcv_monthLabels` that will use the `MonthArrayTitleFormatter` to format the title with the months provided.
-
-### WeekDays
-
-You can supply a custom formatter for weekdays with a `WeekDayFormatter` by calling `setWeekDayFormatter()`.
-The default implementation is a `CalendarWeekDayFormatter`, which uses `java.util.Calendar` to get weekday labels.
-We also provide `ArrayWeekDayFormatter`, which uses `CharSequence` array as week day labels.
-You can set `mcv_weekDayLabels` in xml with a string array resource, which will set an `ArrayWeekDayFormatter`.
-
-### DayFormatter
-
-You can set custom day labels by passing a `DayFormatter` to the `setDayFormatter()` method.
-The default is a `DateFormatDayFormatter`, which uses a `SimpleDateFormat` with format `"d"`.
-
-Unlike the formatters for Header or WeekDays, this formatter returns a String.
-If you want to use spans on your day labels, you will need to use the [decorator api](DECORATORS.md).
-
-
-## Text Appearances
-
-There are three different text appearances you can set:
-
-* Header: `mcv_headerTextAppearance` or `setHeaderTextAppearance()`
-* Weekday: `mcv_weekDayTextAppearance` or `setWeekDayTextAppearance()`
-* Date: `mcv_dateTextAppearance` or `setDateTextAppearance()`
-
-The header text appearance is used for the topbar month label.
-The weekday is for the row of weekday labels, and date is for the individual days.
-
-For date text appearance, make sure you respond to presses and states. [Read more here](CUSTOM_SELECTORS.md).
diff --git a/docs/CUSTOMIZATION_BUILDER.md b/docs/CUSTOMIZATION_BUILDER.md
deleted file mode 100644
index 0b18dbab..00000000
--- a/docs/CUSTOMIZATION_BUILDER.md
+++ /dev/null
@@ -1,57 +0,0 @@
-State builder
-=============
-
-Certain parameters are only modifiable using the state builder of the `MaterialCalendarView`.
-Using the builder prevents from updating the view each time one of the setters is called. The view is updated when calling `Builder#commit()` and that improve performances.
-Previously, the fields could be customize using casual setters.
-
-Here is a concrete example of how to use the builder:
-
-```java
-mcv.state().edit()
- .setFirstDayOfWeek(Calendar.WEDNESDAY)
- .setMinimumDate(CalendarDay.from(2016, 4, 3))
- .setMaximumDate(CalendarDay.from(2016, 5, 12))
- .setCalendarDisplayMode(CalendarMode.WEEKS)
- .setSaveCurrentPosition(true)
- .commit();
-```
-
-## state.edit() vs newState()
-
-Using `mcv.state().edit()` will preserve the current state of the `MaterialCalendarView` while `mcv.newState()` will initialize the builder with new parameters.
-Only the fields that are modifiable using the builder can be reset or edit. Here is the list of the fields:
-
-- First Day Of Week
-- Minimum Date
-- Maximum Date
-- Calendar Display Mode
-
-As an example, if you are setting `firstDayOfWeek` inside your xml, and you want to preserve the field when using the builder, you should use `state.edit()`.
-However if you don't want to preserve any current parameters from the list above, use `newState()`. In most cases `state.edit()` should be the right method to use.
-
-### First Day Of The Week
-
-The default first day of the week is Sunday. You can set a custom day of the week by setting `mcv_firstDayOfWeek` in xml, or by calling `setFirstDayOfWeek()`.
-The xml attribute is an enum of `sunday` through `saturday` and `setFirstDayOfWeek()` accepts values from `java.util.Calendar` such as `Calendar.MONDAY`.
-
-
-### Date Ranges
-
-By default, the calendar displays months for 200 years before today and 200 years after.
-You can specify different minimum and maximum dates by calling `setMinimumDate(CalendarDay)` and `setMaximumDate(CalendarDay)`.
-Passing `null` will reset back to the default 200 years.
-There are also convenience methods that accept a `Calendar` or a `Date` object and convert them to a `CalendarDay` using the relevant `CalendarDay.from()` factory method.
-
-### Calendar Display Mode
-
-`MaterialCalendarView` propose two display modes: weekly and monthly. You can set the display mode in your xml using the attribute `mcv_calendarMode` with `month` for monthly mode, or `week` for weekly mode.
-You can also use the builder `setCalendarDisplayMode(CalendarMode)` parameter.
-
-It is **important** to note that the `CalendarMode.WEEKS` is still experimental.
-
-### Save current position between week and month mode
-
-`SaveCurrentPosition` is set to false by default. When switching between week and month mode, the view redirect you to the today's date.
-
-When `setSaveCurrentPosition` is set to `true`, the calendar will stay on the current position or last selected date.
\ No newline at end of file
diff --git a/docs/CUSTOM_SELECTORS.md b/docs/CUSTOM_SELECTORS.md
deleted file mode 100644
index fd0a1cab..00000000
--- a/docs/CUSTOM_SELECTORS.md
+++ /dev/null
@@ -1,99 +0,0 @@
-Custom Selectors
-================
-
-This doc describes how to create custom stateful drawables and colors to be used in the view.
-
-## Stateful-ness in Material CalendarView
-
-There are several places in the view where reacting to state would be useful.
-The most obvious is the date selection indicator, but state can also be represented with custom
-backgrounds set by decorators or text colors.
-
-The state that is used to represent selected days is `android:checked`.
-Days can also be disabled, which is represented with `android:enabled`.
-
-### Drawables
-
-If you want to set a custom selector or background, you'll need to make sure your drawable responds to state.
-This is most easily done by using a `selector` in your xml or use `StateListDrawable`.
-
-Here is a basic example of a selector:
-
-```xml
-
-
-
-
-
-
-
-
-```
-
-This is the (truncated) code used to generate the default selector:
-
- ```java
-private static Drawable generateSelector() {
- StateListDrawable drawable = new StateListDrawable();
- drawable.setExitFadeDuration(...);
- drawable.addState(new int[]{android.R.attr.state_checked}, generateCircleDrawable(...));
- drawable.addState(new int[]{android.R.attr.state_pressed}, generateCircleDrawable(...));
- drawable.addState(new int[]{}, generateCircleDrawable(Color.TRANSPARENT));
- return drawable;
-}
- ```
-
-### Text Color
-
-In some cases, the default text color isn't the one you want.
-In this case, you will need to create a custom text appearance style that sets the text color you need.
-You do this by setting `mcv_dateTextAppearance` or calling `setDateTextAppearance()`.
-This library provides a text appearance style `TextAppearance.MaterialCalendarWidget.Date`, for you to extend.
-And it also has two stateful colors, `mcv_text_date_dark` or `mcv_text_date_light` (which is the default).
-
-Here's an example for a dark theme and a light selector:
-
-```xml
-
-```
-
-Here's an example for a dark theme and a dark selector:
-
-```xml
-
-
-```
-```xml
-
-
-
-
-
-
-
-
-
-
-
-
-```
diff --git a/docs/DECORATORS.md b/docs/DECORATORS.md
deleted file mode 100644
index 64499ae8..00000000
--- a/docs/DECORATORS.md
+++ /dev/null
@@ -1,87 +0,0 @@
-DayViewDecorators
-=================
-
-The decorator API is a flexible way to customize individual days.
-Specifically, it allows you to:
-
-* Set custom backgrounds
-* Set custom selectors
-* Apply spans to the entire day's text
- * We provide `DotSpan` which will draw a dot centered below the text
-* Set dates as disabled
-
-This doc will explain how the API works and examples of how to use it.
-
-## How It Works
-
-A `DayViewDecorator` is an interface that has only two methods you need to implement, `shouldDecorate(CalendarDay)` and `decorate(DayViewFacade)`.
-`shouldDecorate()` is called for every date in the calendar to determine if the decorator should be applied to that date.
-`decorate()` is called only one time to gather the customizations used for this decorator.
-This is so we can cache the decorations and efficiently apply them to many days.
-
-The `decorate()` method provides you with a `DayViewFacade` that has four methods to allow decoration:
-
-1. `setBackgroundDrawable(Drawable)`
- * You can set a drawable to draw behind everything else.
- * This also responds to state changes.
-2. `setSelectionDrawable(Drawable)`
- * This customizes the selection indicator.
-3. `addSpan(Object)`
- * Allows you to set a span on the entire day label.
- * We provide a `DotSpan` that draws a dot centered below the label.
- * For an introduction to spans, see [this article](http://androidcocktail.blogspot.com/2014/03/android-spannablestring-example.html).
- * If you want to learn more about custom spans, check out [this article](http://flavienlaurent.com/blog/2014/01/31/spans/).
- * The span is set using `setSpan(yourSpan, 0, label.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);`
-4. `setDaysDisabled(boolean)`
- * Allows you to disable and re-enable days.
- * This will not affect minimum and maximum dates.
- * Days decorated as disabled can be re-enabled with other decorators.
-
-If one of your decorators changes after it has been added to the calendar view,
-make sure you call `invalidateDecorators()` to have those changes reflected.
-The decorators are automatically invalidated when you add or remove decorators from the view.
-
-To add a decorator to the calendar, you can call `addDecorator()`.
-The order that decorators are added are the order in which they will be applied.
-You can remove decorators by calling `removeDecorator()` or `removeDecorators()`.
-
-When implementing a `DayViewDecorator`, make sure that they are as efficient as possible.
-Remember that `shouldDecorate()` needs to be called 42 times for each month view.
-An easy way to be more efficient is to convert your data to `CalendarDay`s outside of `shouldDecorate()`.
-
-## Responding To State
-
-If you provide custom drawables, make sure they respond to touches and states.
-Read more in the [custom selector documentation](CUSTOM_SELECTORS.md).
-
-## Examples
-
-This section details some example uses.
-You can also check out the sample app's `BasicActivityDecorated` activity for some examples.
-
-### Events
-
-Here is a simple example decorator that will draw a dot under a set of dates.
-
-```java
-public class EventDecorator implements DayViewDecorator {
-
- private final int color;
- private final HashSet dates;
-
- public EventDecorator(int color, Collection dates) {
- this.color = color;
- this.dates = new HashSet<>(dates);
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return dates.contains(day);
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.addSpan(new DotSpan(5, color));
- }
-}
-```
diff --git a/docs/README.md b/docs/README.md
deleted file mode 100644
index ee4468d5..00000000
--- a/docs/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-Documentation
-=============
-
-This is where in depth documentation will be going.
-
-## Customization Options
-
-Check out most of the customization options [here](CUSTOMIZATION.md).
-
-## Customization using state builder
-
-Some of the customization can be made using a builder. Using a builder for those parameters helps preventing bugs and improves performances.
-Those parameters are:
-
-- [First Day Of Week](CUSTOMIZATION_BUILDER.md#first-day-of-the-week)
-- [Minimum Date](CUSTOMIZATION_BUILDER.md#date-ranges)
-- [Maximum Date](CUSTOMIZATION_BUILDER.md#date-ranges)
-- [Calendar Display Mode](CUSTOMIZATION_BUILDER.md#calendar-display-mode)
-
-The documentation is available [here](CUSTOMIZATION_BUILDER.md).
-
-## Events, Highlighting, Custom Selectors, and More!
-
-All of this and more can be done via the decorator api. Please check out the [decorator documentation](DECORATORS.md).
-
-## Custom Selectors and Colors
-
-If you provide custom drawables or colors, you'll want to make sure they respond to state.
-Check out the [documentation for custom states](CUSTOM_SELECTORS.md).
-
-## TODO
-
-- Write and organize the documentation. Focus on customization with real world scenarios.
-- Improve performances.
-- Add test cases.
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1b1340d5..64544d28 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
-distributionBase = GRADLE_USER_HOME
-distributionPath = wrapper/dists
-distributionUrl = https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
-zipStoreBase = GRADLE_USER_HOME
-zipStorePath = wrapper/dists
+#Tue Apr 07 21:03:41 EET 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/images/hero.png b/images/hero.png
deleted file mode 100644
index 1f678e06..00000000
Binary files a/images/hero.png and /dev/null differ
diff --git a/images/screencast.gif b/images/screencast.gif
deleted file mode 100644
index 94b826fb..00000000
Binary files a/images/screencast.gif and /dev/null differ
diff --git a/library/build.gradle b/library/build.gradle
index 824727a5..6cc36232 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -3,11 +3,11 @@ apply plugin: 'maven'
apply plugin: 'com.github.dcendents.android-maven'
android {
- compileSdkVersion rootProject.ext.compileSdkVersion
+ compileSdkVersion 28
defaultConfig {
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
+ minSdkVersion 16
+ targetSdkVersion 27
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
@@ -23,6 +23,10 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+ buildTypes {
+ staging {
+ }
+ }
}
group = "com.github.prolificinteractive"
@@ -30,13 +34,13 @@ version = android.defaultConfig.versionName
archivesBaseName = 'material-calendarview'
dependencies {
- implementation rootProject.ext.threeTenAbp
- implementation rootProject.ext.supportV4
- implementation rootProject.ext.supportAppCompat
- implementation rootProject.ext.supportAnnotations
+ implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'
+ implementation 'androidx.appcompat:appcompat:1.0.0'
+ implementation 'androidx.annotation:annotation:1.0.0'
- rootProject.ext.testDep.each { testImplementation it }
- rootProject.ext.androidTestDep.each { androidTestImplementation it }
+ // SSP / SDP
+ implementation 'com.intuit.ssp:ssp-android:1.0.6'
+ implementation 'com.intuit.sdp:sdp-android:1.0.6'
}
tasks.withType(Javadoc) {
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
index 095af6b0..d1e1a33c 100644
--- a/library/src/main/AndroidManifest.xml
+++ b/library/src/main/AndroidManifest.xml
@@ -1,14 +1,12 @@
+ package="com.prolificinteractive.materialcalendarview">
-
-
-
+
+
+
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/AnimatorListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/AnimatorListener.java
index cf9ee34d..d4a793be 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/AnimatorListener.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/AnimatorListener.java
@@ -3,19 +3,19 @@
import android.animation.Animator;
class AnimatorListener implements Animator.AnimatorListener {
- @Override
- public void onAnimationStart(Animator animator) {
- }
+ @Override
+ public void onAnimationStart(Animator animator) {
+ }
- @Override
- public void onAnimationEnd(Animator animator) {
- }
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ }
- @Override
- public void onAnimationCancel(Animator animator) {
- }
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ }
- @Override
- public void onAnimationRepeat(Animator animator) {
- }
+ @Override
+ public void onAnimationRepeat(Animator animator) {
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarDay.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarDay.java
index 4a0b073d..1f1a0e13 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarDay.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarDay.java
@@ -2,8 +2,9 @@
import android.os.Parcel;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import org.threeten.bp.LocalDate;
/**
@@ -11,176 +12,184 @@
*/
public final class CalendarDay implements Parcelable {
- /**
- * Everything is based on this variable for {@link CalendarDay}.
- */
- @NonNull private final LocalDate date;
-
- /**
- * @param year new instance's year
- * @param month new instance's month as defined by {@linkplain java.util.Calendar}
- * @param day new instance's day of month
- */
- private CalendarDay(final int year, final int month, final int day) {
- date = LocalDate.of(year, month, day);
- }
-
- /**
- * @param date {@link LocalDate} instance
- */
- private CalendarDay(@NonNull final LocalDate date) {
- this.date = date;
- }
-
- /**
- * Get a new instance set to today
- *
- * @return CalendarDay set to today's date
- */
- @NonNull public static CalendarDay today() {
- return from(LocalDate.now());
- }
-
- /**
- * Get a new instance set to the specified day
- *
- * @param year new instance's year
- * @param month new instance's month as defined by {@linkplain java.util.Calendar}
- * @param day new instance's day of month
- * @return CalendarDay set to the specified date
- */
- @NonNull public static CalendarDay from(int year, int month, int day) {
- return new CalendarDay(year, month, day);
- }
-
- /**
- * Get a new instance set to the specified day
- *
- * @param date {@linkplain LocalDate} to pull date information from. Passing null will return null
- * @return CalendarDay set to the specified date
- */
- public static CalendarDay from(@Nullable LocalDate date) {
- if (date == null) {
- return null;
- }
- return new CalendarDay(date);
- }
-
- /**
- * Get the year
- *
- * @return the year for this day
- */
- public int getYear() {
- return date.getYear();
- }
-
- /**
- * Get the month, represented by values from {@linkplain LocalDate}
- *
- * @return the month of the year as defined by {@linkplain LocalDate}
- */
- public int getMonth() {
- return date.getMonthValue();
- }
-
- /**
- * Get the day
- *
- * @return the day of the month for this day
- */
- public int getDay() {
- return date.getDayOfMonth();
- }
-
- /**
- * Get this day as a {@linkplain LocalDate}
- *
- * @return a date with this days information
- */
- @NonNull public LocalDate getDate() {
- return date;
- }
-
- /**
- * Determine if this day is within a specified range
- *
- * @param minDate the earliest day, may be null
- * @param maxDate the latest day, may be null
- * @return true if the between (inclusive) the min and max dates.
- */
- public boolean isInRange(@Nullable CalendarDay minDate, @Nullable CalendarDay maxDate) {
- return !(minDate != null && minDate.isAfter(this)) &&
- !(maxDate != null && maxDate.isBefore(this));
- }
-
- /**
- * Determine if this day is before the given instance
- *
- * @param other the other day to test
- * @return true if this is before other, false if equal or after
- */
- public boolean isBefore(@NonNull final CalendarDay other) {
- return date.isBefore(other.getDate());
- }
-
- /**
- * Determine if this day is after the given instance
- *
- * @param other the other day to test
- * @return true if this is after other, false if equal or before
- */
- public boolean isAfter(@NonNull final CalendarDay other) {
- return date.isAfter(other.getDate());
- }
-
- @Override public boolean equals(Object o) {
- return o instanceof CalendarDay && date.equals(((CalendarDay) o).getDate());
- }
-
- @Override
- public int hashCode() {
- return hashCode(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
- }
-
- private static int hashCode(int year, int month, int day) {
- //Should produce hashes like "20150401"
- return (year * 10000) + (month * 100) + day;
- }
-
- @Override
- public String toString() {
- return "CalendarDay{" + date.getYear() + "-" + date.getMonthValue() + "-"
- + date.getDayOfMonth() + "}";
- }
-
- /*
- * Parcelable Stuff
- */
-
- public CalendarDay(Parcel in) {
- this(in.readInt(), in.readInt(), in.readInt());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(date.getYear());
- dest.writeInt(date.getMonthValue());
- dest.writeInt(date.getDayOfMonth());
- }
-
- public static final Creator CREATOR = new Creator() {
- public CalendarDay createFromParcel(Parcel in) {
- return new CalendarDay(in);
- }
-
- public CalendarDay[] newArray(int size) {
- return new CalendarDay[size];
- }
- };
+ public static final Creator CREATOR = new Creator() {
+ public CalendarDay createFromParcel(Parcel in) {
+ return new CalendarDay(in);
+ }
+
+ public CalendarDay[] newArray(int size) {
+ return new CalendarDay[size];
+ }
+ };
+ /**
+ * Everything is based on this variable for {@link CalendarDay}.
+ */
+ @NonNull
+ private final LocalDate date;
+
+ /**
+ * @param year new instance's year
+ * @param month new instance's month as defined by {@linkplain java.util.Calendar}
+ * @param day new instance's day of month
+ */
+ private CalendarDay(final int year, final int month, final int day) {
+ date = LocalDate.of(year, month, day);
+ }
+
+ /**
+ * @param date {@link LocalDate} instance
+ */
+ private CalendarDay(@NonNull final LocalDate date) {
+ this.date = date;
+ }
+
+ public CalendarDay(Parcel in) {
+ this(in.readInt(), in.readInt(), in.readInt());
+ }
+
+ /**
+ * Get a new instance set to today
+ *
+ * @return CalendarDay set to today's date
+ */
+ @NonNull
+ public static CalendarDay today() {
+ return from(LocalDate.now());
+ }
+
+ /**
+ * Get a new instance set to the specified day
+ *
+ * @param year new instance's year
+ * @param month new instance's month as defined by {@linkplain java.util.Calendar}
+ * @param day new instance's day of month
+ * @return CalendarDay set to the specified date
+ */
+ @NonNull
+ public static CalendarDay from(int year, int month, int day) {
+ return new CalendarDay(year, month, day);
+ }
+
+ /**
+ * Get a new instance set to the specified day
+ *
+ * @param date {@linkplain LocalDate} to pull date information from. Passing null will return null
+ * @return CalendarDay set to the specified date
+ */
+ public static CalendarDay from(@Nullable LocalDate date) {
+ if (date == null) {
+ return null;
+ }
+ return new CalendarDay(date);
+ }
+
+ private static int hashCode(int year, int month, int day) {
+ //Should produce hashes like "20150401"
+ return (year * 10000) + (month * 100) + day;
+ }
+
+ /**
+ * Get the year
+ *
+ * @return the year for this day
+ */
+ public int getYear() {
+ return date.getYear();
+ }
+
+ /**
+ * Get the month, represented by values from {@linkplain LocalDate}
+ *
+ * @return the month of the year as defined by {@linkplain LocalDate}
+ */
+ public int getMonth() {
+ return date.getMonthValue();
+ }
+
+ /**
+ * Get the day
+ *
+ * @return the day of the month for this day
+ */
+ public int getDay() {
+ return date.getDayOfMonth();
+ }
+
+ /**
+ * Get this day as a {@linkplain LocalDate}
+ *
+ * @return a date with this days information
+ */
+ @NonNull
+ public LocalDate getDate() {
+ return date;
+ }
+
+ public String getFormattedSelectedDate() {
+ return date.getDayOfMonth() + "-" + date.getMonthValue() + "-" + date.getYear();
+ }
+
+ /**
+ * Determine if this day is within a specified range
+ *
+ * @param minDate the earliest day, may be null
+ * @param maxDate the latest day, may be null
+ * @return true if the between (inclusive) the min and max dates.
+ */
+ public boolean isInRange(@Nullable CalendarDay minDate, @Nullable CalendarDay maxDate) {
+ return !(minDate != null && minDate.isAfter(this)) &&
+ !(maxDate != null && maxDate.isBefore(this));
+ }
+
+ /**
+ * Determine if this day is before the given instance
+ *
+ * @param other the other day to test
+ * @return true if this is before other, false if equal or after
+ */
+ public boolean isBefore(@NonNull final CalendarDay other) {
+ return date.isBefore(other.getDate());
+ }
+
+ /**
+ * Determine if this day is after the given instance
+ *
+ * @param other the other day to test
+ * @return true if this is after other, false if equal or before
+ */
+ public boolean isAfter(@NonNull final CalendarDay other) {
+ return date.isAfter(other.getDate());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof CalendarDay && date.equals(((CalendarDay) o).getDate());
+ }
+
+ /*
+ * Parcelable Stuff
+ */
+
+ @Override
+ public int hashCode() {
+ return hashCode(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
+ }
+
+ @Override
+ public String toString() {
+ return "CalendarDay{" + date.getYear() + "-" + date.getMonthValue() + "-"
+ + date.getDayOfMonth() + "}";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(date.getYear());
+ dest.writeInt(date.getMonthValue());
+ dest.writeInt(date.getDayOfMonth());
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarMode.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarMode.java
index 3c704ad8..fa53c8ca 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarMode.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarMode.java
@@ -5,21 +5,21 @@
*/
public enum CalendarMode {
- /**
- * Month Mode to display an entire month per page.
- */
- MONTHS(6),
- /**
- * Week mode that shows the calendar week by week.
- */
- WEEKS(1);
+ /**
+ * Month Mode to display an entire month per page.
+ */
+ MONTHS(6),
+ /**
+ * Week mode that shows the calendar week by week.
+ */
+ WEEKS(1);
- /**
- * Number of visible weeks per calendar mode.
- */
- final int visibleWeeksCount;
+ /**
+ * Number of visible weeks per calendar mode.
+ */
+ final int visibleWeeksCount;
- CalendarMode(int visibleWeeksCount) {
- this.visibleWeeksCount = visibleWeeksCount;
- }
+ CalendarMode(int visibleWeeksCount) {
+ this.visibleWeeksCount = visibleWeeksCount;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPager.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPager.java
index 33562555..60109815 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPager.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPager.java
@@ -1,68 +1,68 @@
package com.prolificinteractive.materialcalendarview;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.view.ViewPager;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.viewpager.widget.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* Custom ViewPager that allows swiping to be disabled.
*/
-class CalendarPager extends ViewPager {
+class CalendarPager extends RtlViewPager {
- private boolean pagingEnabled = true;
+ private boolean pagingEnabled = true;
- public CalendarPager(@NonNull final Context context) {
- super(context);
- }
+ public CalendarPager(@NonNull final Context context) {
+ super(context);
+ }
- public CalendarPager(@NonNull final Context context, @Nullable final AttributeSet attrs) {
- super(context, attrs);
- }
+ public CalendarPager(@NonNull final Context context, @Nullable final AttributeSet attrs) {
+ super(context, attrs);
+ }
- /**
- * enable disable viewpager scroll
- *
- * @param pagingEnabled false to disable paging, true for paging (default)
- */
- public void setPagingEnabled(boolean pagingEnabled) {
- this.pagingEnabled = pagingEnabled;
- }
-
- /**
- * @return is this viewpager allowed to page
- */
- public boolean isPagingEnabled() {
- return pagingEnabled;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- return pagingEnabled && super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- return pagingEnabled && super.onTouchEvent(ev);
- }
-
- @Override
- public boolean canScrollVertically(int direction) {
/**
- * disables scrolling vertically when paging disabled, fixes scrolling
- * for nested {@link android.support.v4.view.ViewPager}
+ * @return is this viewpager allowed to page
*/
- return pagingEnabled && super.canScrollVertically(direction);
- }
+ public boolean isPagingEnabled() {
+ return pagingEnabled;
+ }
- @Override
- public boolean canScrollHorizontally(int direction) {
/**
- * disables scrolling horizontally when paging disabled, fixes scrolling
- * for nested {@link android.support.v4.view.ViewPager}
+ * enable disable viewpager scroll
+ *
+ * @param pagingEnabled false to disable paging, true for paging (default)
*/
- return pagingEnabled && super.canScrollHorizontally(direction);
- }
+ public void setPagingEnabled(boolean pagingEnabled) {
+ this.pagingEnabled = pagingEnabled;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return pagingEnabled && super.onInterceptTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return pagingEnabled && super.onTouchEvent(ev);
+ }
+
+ @Override
+ public boolean canScrollVertically(int direction) {
+ /**
+ * disables scrolling vertically when paging disabled, fixes scrolling
+ * for nested {@link ViewPager}
+ */
+ return pagingEnabled && super.canScrollVertically(direction);
+ }
+
+ @Override
+ public boolean canScrollHorizontally(int direction) {
+ /**
+ * disables scrolling horizontally when paging disabled, fixes scrolling
+ * for nested {@link ViewPager}
+ */
+ return pagingEnabled && super.canScrollHorizontally(direction);
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerAdapter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerAdapter.java
index d4c68eae..17a68954 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerAdapter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerAdapter.java
@@ -1,18 +1,22 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.view.PagerAdapter;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.viewpager.widget.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
+
+import com.prolificinteractive.materialcalendarview.format.DateFormatDayFormatter;
import com.prolificinteractive.materialcalendarview.MaterialCalendarView.ShowOtherDates;
import com.prolificinteractive.materialcalendarview.format.DayFormatter;
import com.prolificinteractive.materialcalendarview.format.TitleFormatter;
import com.prolificinteractive.materialcalendarview.format.WeekDayFormatter;
+
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+
import org.threeten.bp.LocalDate;
/**
@@ -20,359 +24,358 @@
*/
abstract class CalendarPagerAdapter extends PagerAdapter {
- private final ArrayDeque currentViews;
-
- protected final MaterialCalendarView mcv;
- private final CalendarDay today;
-
- @NonNull private TitleFormatter titleFormatter = TitleFormatter.DEFAULT;
- private Integer color = null;
- private Integer dateTextAppearance = null;
- private Integer weekDayTextAppearance = null;
- @ShowOtherDates
- private int showOtherDates = MaterialCalendarView.SHOW_DEFAULTS;
- private CalendarDay minDate = null;
- private CalendarDay maxDate = null;
- private DateRangeIndex rangeIndex;
- private List selectedDates = new ArrayList<>();
- private WeekDayFormatter weekDayFormatter = WeekDayFormatter.DEFAULT;
- private DayFormatter dayFormatter = DayFormatter.DEFAULT;
- private DayFormatter dayFormatterContentDescription = dayFormatter;
- private List decorators = new ArrayList<>();
- private List decoratorResults = null;
- private boolean selectionEnabled = true;
- boolean showWeekDays;
-
- CalendarPagerAdapter(MaterialCalendarView mcv) {
- this.mcv = mcv;
- this.today = CalendarDay.today();
- currentViews = new ArrayDeque<>();
- currentViews.iterator();
- setRangeDates(null, null);
- }
-
- public void setDecorators(List decorators) {
- this.decorators = decorators;
- invalidateDecorators();
- }
-
- public void invalidateDecorators() {
- decoratorResults = new ArrayList<>();
- for (DayViewDecorator decorator : decorators) {
- DayViewFacade facade = new DayViewFacade();
- decorator.decorate(facade);
- if (facade.isDecorated()) {
- decoratorResults.add(new DecoratorResult(decorator, facade));
- }
- }
- for (V pagerView : currentViews) {
- pagerView.setDayViewDecorators(decoratorResults);
- }
- }
-
- @Override
- public int getCount() {
- return rangeIndex.getCount();
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- return titleFormatter.format(getItem(position));
- }
-
- public CalendarPagerAdapter> migrateStateAndReturn(CalendarPagerAdapter> newAdapter) {
- newAdapter.titleFormatter = titleFormatter;
- newAdapter.color = color;
- newAdapter.dateTextAppearance = dateTextAppearance;
- newAdapter.weekDayTextAppearance = weekDayTextAppearance;
- newAdapter.showOtherDates = showOtherDates;
- newAdapter.minDate = minDate;
- newAdapter.maxDate = maxDate;
- newAdapter.selectedDates = selectedDates;
- newAdapter.weekDayFormatter = weekDayFormatter;
- newAdapter.dayFormatter = dayFormatter;
- newAdapter.dayFormatterContentDescription = dayFormatterContentDescription;
- newAdapter.decorators = decorators;
- newAdapter.decoratorResults = decoratorResults;
- newAdapter.selectionEnabled = selectionEnabled;
- return newAdapter;
- }
-
- public int getIndexForDay(CalendarDay day) {
- if (day == null) {
- return getCount() / 2;
- }
- if (minDate != null && day.isBefore(minDate)) {
- return 0;
- }
- if (maxDate != null && day.isAfter(maxDate)) {
- return getCount() - 1;
- }
- return rangeIndex.indexOf(day);
- }
-
- protected abstract V createView(int position);
-
- protected abstract int indexOf(V view);
-
- protected abstract boolean isInstanceOfView(Object object);
-
- protected abstract DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max);
-
- @Override
- public int getItemPosition(@NonNull Object object) {
- if (!(isInstanceOfView(object))) {
- return POSITION_NONE;
- }
- CalendarPagerView pagerView = (CalendarPagerView) object;
- CalendarDay firstViewDay = pagerView.getFirstViewDay();
- if (firstViewDay == null) {
- return POSITION_NONE;
- }
- int index = indexOf((V) object);
- if (index < 0) {
- return POSITION_NONE;
- }
- return index;
- }
-
- @NonNull
- @Override
- public Object instantiateItem(@NonNull ViewGroup container, int position) {
- V pagerView = createView(position);
- pagerView.setContentDescription(mcv.getCalendarContentDescription());
- pagerView.setAlpha(0);
- pagerView.setSelectionEnabled(selectionEnabled);
-
- pagerView.setWeekDayFormatter(weekDayFormatter);
- pagerView.setDayFormatter(dayFormatter);
- pagerView.setDayFormatterContentDescription(dayFormatterContentDescription);
- if (color != null) {
- pagerView.setSelectionColor(color);
- }
- if (dateTextAppearance != null) {
- pagerView.setDateTextAppearance(dateTextAppearance);
- }
- if (weekDayTextAppearance != null) {
- pagerView.setWeekDayTextAppearance(weekDayTextAppearance);
- }
- pagerView.setShowOtherDates(showOtherDates);
- pagerView.setMinimumDate(minDate);
- pagerView.setMaximumDate(maxDate);
- pagerView.setSelectedDates(selectedDates);
-
- container.addView(pagerView);
- currentViews.add(pagerView);
+ protected final MaterialCalendarView mcv;
+ private final ArrayDeque currentViews;
+ private final CalendarDay today;
+ boolean showWeekDays;
+ @NonNull
+ private TitleFormatter titleFormatter = TitleFormatter.DEFAULT;
+ private Integer color = null;
+ private Integer dateTextAppearance = null;
+ private Integer weekDayTextAppearance = null;
+ @ShowOtherDates
+ private int showOtherDates = MaterialCalendarView.SHOW_DEFAULTS;
+ private CalendarDay minDate = null;
+ private CalendarDay maxDate = null;
+ private DateRangeIndex rangeIndex;
+ private List selectedDates = new ArrayList<>();
+ private WeekDayFormatter weekDayFormatter = WeekDayFormatter.DEFAULT;
+ private DayFormatter dayFormatter = DateFormatDayFormatter.getInstance();
+ private DayFormatter dayFormatterContentDescription = dayFormatter;
+ private List decorators = new ArrayList<>();
+ private List decoratorResults = null;
+ private boolean selectionEnabled = true;
+
+ CalendarPagerAdapter(MaterialCalendarView mcv) {
+ this.mcv = mcv;
+ this.today = CalendarDay.today();
+ currentViews = new ArrayDeque<>();
+ currentViews.iterator();
+ setRangeDates(null, null);
+ }
- pagerView.setDayViewDecorators(decoratorResults);
-
- return pagerView;
- }
-
- public void setShowWeekDays(boolean showWeekDays) {
- this.showWeekDays = showWeekDays;
- }
+ public void setDecorators(List decorators) {
+ this.decorators = decorators;
+ invalidateDecorators();
+ }
+
+ public void invalidateDecorators() {
+ decoratorResults = new ArrayList<>();
+ for (DayViewDecorator decorator : decorators) {
+ DayViewFacade facade = new DayViewFacade();
+ decorator.decorate(facade);
+ if (facade.isDecorated()) {
+ decoratorResults.add(new DecoratorResult(decorator, facade));
+ }
+ }
+ for (V pagerView : currentViews) {
+ pagerView.setDayViewDecorators(decoratorResults);
+ }
+ }
- public boolean isShowWeekDays() {
- return showWeekDays;
- }
+ @Override
+ public int getCount() {
+ return rangeIndex.getCount();
+ }
- public void setSelectionEnabled(boolean enabled) {
- selectionEnabled = enabled;
- for (V pagerView : currentViews) {
- pagerView.setSelectionEnabled(selectionEnabled);
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return titleFormatter.format(getItem(position));
}
- }
- @Override
- public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
- V pagerView = (V) object;
- currentViews.remove(pagerView);
- container.removeView(pagerView);
- }
+ public CalendarPagerAdapter> migrateStateAndReturn(CalendarPagerAdapter> newAdapter) {
+ newAdapter.titleFormatter = titleFormatter;
+ newAdapter.color = color;
+ newAdapter.dateTextAppearance = dateTextAppearance;
+ newAdapter.weekDayTextAppearance = weekDayTextAppearance;
+ newAdapter.showOtherDates = showOtherDates;
+ newAdapter.minDate = minDate;
+ newAdapter.maxDate = maxDate;
+ newAdapter.selectedDates = selectedDates;
+ newAdapter.weekDayFormatter = weekDayFormatter;
+ newAdapter.dayFormatter = dayFormatter;
+ newAdapter.dayFormatterContentDescription = dayFormatterContentDescription;
+ newAdapter.decorators = decorators;
+ newAdapter.decoratorResults = decoratorResults;
+ newAdapter.selectionEnabled = selectionEnabled;
+ return newAdapter;
+ }
- @Override
- public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
- return view == object;
- }
+ public int getIndexForDay(CalendarDay day) {
+ if (day == null) {
+ return getCount() / 2;
+ }
+ if (minDate != null && day.isBefore(minDate)) {
+ return 0;
+ }
+ if (maxDate != null && day.isAfter(maxDate)) {
+ return getCount() - 1;
+ }
+ return rangeIndex.indexOf(day);
+ }
- public void setTitleFormatter(@Nullable TitleFormatter titleFormatter) {
- this.titleFormatter = titleFormatter == null ? TitleFormatter.DEFAULT : titleFormatter;
- }
+ protected abstract V createView(int position);
+
+ protected abstract int indexOf(V view);
+
+ protected abstract boolean isInstanceOfView(Object object);
+
+ protected abstract DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max);
+
+ @Override
+ public int getItemPosition(@NonNull Object object) {
+ if (!(isInstanceOfView(object))) {
+ return POSITION_NONE;
+ }
+ CalendarPagerView pagerView = (CalendarPagerView) object;
+ CalendarDay firstViewDay = pagerView.getFirstViewDay();
+ if (firstViewDay == null) {
+ return POSITION_NONE;
+ }
+ int index = indexOf((V) object);
+ if (index < 0) {
+ return POSITION_NONE;
+ }
+ return index;
+ }
- public void setSelectionColor(int color) {
- this.color = color;
- for (V pagerView : currentViews) {
- pagerView.setSelectionColor(color);
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
+ V pagerView = createView(position);
+ pagerView.setContentDescription(mcv.getCalendarContentDescription());
+ pagerView.setAlpha(0);
+ pagerView.setSelectionEnabled(selectionEnabled);
+
+ pagerView.setWeekDayFormatter(weekDayFormatter);
+ pagerView.setDayFormatter(dayFormatter);
+ pagerView.setDayFormatterContentDescription(dayFormatterContentDescription);
+ if (color != null) {
+ pagerView.setSelectionColor(color);
+ }
+ if (dateTextAppearance != null) {
+ pagerView.setDateTextAppearance(dateTextAppearance);
+ }
+ if (weekDayTextAppearance != null) {
+ pagerView.setWeekDayTextAppearance(weekDayTextAppearance);
+ }
+ pagerView.setShowOtherDates(showOtherDates);
+ pagerView.setMinimumDate(minDate);
+ pagerView.setMaximumDate(maxDate);
+ pagerView.setSelectedDates(selectedDates);
+
+ container.addView(pagerView);
+ currentViews.add(pagerView);
+
+ pagerView.setDayViewDecorators(decoratorResults);
+
+ return pagerView;
}
- }
- public void setDateTextAppearance(int taId) {
- if (taId == 0) {
- return;
+ public boolean isShowWeekDays() {
+ return showWeekDays;
}
- this.dateTextAppearance = taId;
- for (V pagerView : currentViews) {
- pagerView.setDateTextAppearance(taId);
+
+ public void setShowWeekDays(boolean showWeekDays) {
+ this.showWeekDays = showWeekDays;
}
- }
- public void setShowOtherDates(@ShowOtherDates int showFlags) {
- this.showOtherDates = showFlags;
- for (V pagerView : currentViews) {
- pagerView.setShowOtherDates(showFlags);
+ public void setSelectionEnabled(boolean enabled) {
+ selectionEnabled = enabled;
+ for (V pagerView : currentViews) {
+ pagerView.setSelectionEnabled(selectionEnabled);
+ }
}
- }
- public void setWeekDayFormatter(WeekDayFormatter formatter) {
- this.weekDayFormatter = formatter;
- for (V pagerView : currentViews) {
- pagerView.setWeekDayFormatter(formatter);
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ V pagerView = (V) object;
+ currentViews.remove(pagerView);
+ container.removeView(pagerView);
}
- }
- public void setDayFormatter(DayFormatter formatter) {
- dayFormatterContentDescription = dayFormatterContentDescription == dayFormatter ?
- formatter : dayFormatterContentDescription;
- this.dayFormatter = formatter;
- for (V pagerView : currentViews) {
- pagerView.setDayFormatter(formatter);
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return view == object;
}
- }
- public void setDayFormatterContentDescription(DayFormatter formatter) {
- dayFormatterContentDescription = formatter;
- for (V pagerView : currentViews) {
- pagerView.setDayFormatterContentDescription(formatter);
+ public void setTitleFormatter(@Nullable TitleFormatter titleFormatter) {
+ this.titleFormatter = titleFormatter == null ? TitleFormatter.DEFAULT : titleFormatter;
}
- }
- @ShowOtherDates
- public int getShowOtherDates() {
- return showOtherDates;
- }
+ public void setSelectionColor(int color) {
+ this.color = color;
+ for (V pagerView : currentViews) {
+ pagerView.setSelectionColor(color);
+ }
+ }
- public void setWeekDayTextAppearance(int taId) {
- if (taId == 0) {
- return;
+ public void setWeekDayFormatter(WeekDayFormatter formatter) {
+ this.weekDayFormatter = formatter;
+ for (V pagerView : currentViews) {
+ pagerView.setWeekDayFormatter(formatter);
+ }
}
- this.weekDayTextAppearance = taId;
- for (V pagerView : currentViews) {
- pagerView.setWeekDayTextAppearance(taId);
+
+ public void setDayFormatter(DayFormatter formatter) {
+ dayFormatterContentDescription = dayFormatterContentDescription == dayFormatter ?
+ formatter : dayFormatterContentDescription;
+ this.dayFormatter = formatter;
+ for (V pagerView : currentViews) {
+ pagerView.setDayFormatter(formatter);
+ }
}
- }
- public void setRangeDates(CalendarDay min, CalendarDay max) {
- this.minDate = min;
- this.maxDate = max;
- for (V pagerView : currentViews) {
- pagerView.setMinimumDate(min);
- pagerView.setMaximumDate(max);
+ public void setDayFormatterContentDescription(DayFormatter formatter) {
+ dayFormatterContentDescription = formatter;
+ for (V pagerView : currentViews) {
+ pagerView.setDayFormatterContentDescription(formatter);
+ }
}
- if (min == null) {
- min = CalendarDay.from(today.getYear() - 200, today.getMonth(), today.getDay());
+ @ShowOtherDates
+ public int getShowOtherDates() {
+ return showOtherDates;
}
- if (max == null) {
- max = CalendarDay.from(today.getYear() + 200, today.getMonth(), today.getDay());
+ public void setShowOtherDates(@ShowOtherDates int showFlags) {
+ this.showOtherDates = showFlags;
+ for (V pagerView : currentViews) {
+ pagerView.setShowOtherDates(showFlags);
+ }
}
- rangeIndex = createRangeIndex(min, max);
+ public void setRangeDates(CalendarDay min, CalendarDay max) {
+ this.minDate = min;
+ this.maxDate = max;
+ for (V pagerView : currentViews) {
+ pagerView.setMinimumDate(min);
+ pagerView.setMaximumDate(max);
+ }
- notifyDataSetChanged();
- invalidateSelectedDates();
- }
+ if (min == null) {
+ min = CalendarDay.from(today.getYear() - 200, today.getMonth(), today.getDay());
+ }
- public DateRangeIndex getRangeIndex() {
- return rangeIndex;
- }
+ if (max == null) {
+ max = CalendarDay.from(today.getYear() + 200, today.getMonth(), today.getDay());
+ }
- public void clearSelections() {
- selectedDates.clear();
- invalidateSelectedDates();
- }
+ rangeIndex = createRangeIndex(min, max);
- /**
- * Select or un-select a day.
- *
- * @param day Day to select or un-select
- * @param selected Whether to select or un-select the day from the list.
- * @see CalendarPagerAdapter#selectRange(CalendarDay, CalendarDay)
- */
- public void setDateSelected(CalendarDay day, boolean selected) {
- if (selected) {
- if (!selectedDates.contains(day)) {
- selectedDates.add(day);
+ notifyDataSetChanged();
invalidateSelectedDates();
- }
- } else {
- if (selectedDates.contains(day)) {
- selectedDates.remove(day);
+ }
+
+ public DateRangeIndex getRangeIndex() {
+ return rangeIndex;
+ }
+
+ public void clearSelections() {
+ selectedDates.clear();
invalidateSelectedDates();
- }
}
- }
- /**
- * Clear the previous selection, select the range of days from first to last, and finally
- * invalidate. First day should be before last day, otherwise the selection won't happen.
- *
- * @param first The first day of the range.
- * @param last The last day in the range.
- * @see CalendarPagerAdapter#setDateSelected(CalendarDay, boolean)
- */
- public void selectRange(final CalendarDay first, final CalendarDay last) {
- selectedDates.clear();
+ /**
+ * Select or un-select a day.
+ *
+ * @param day Day to select or un-select
+ * @param selected Whether to select or un-select the day from the list.
+ * @see CalendarPagerAdapter#selectRange(CalendarDay, CalendarDay)
+ */
+ public void setDateSelected(CalendarDay day, boolean selected) {
+ if (selected) {
+ if (!selectedDates.contains(day)) {
+ selectedDates.add(day);
+ invalidateSelectedDates();
+ }
+ } else {
+ if (selectedDates.contains(day)) {
+ selectedDates.remove(day);
+ invalidateSelectedDates();
+ }
+ }
+ }
+
+ /**
+ * Clear the previous selection, select the range of days from first to last, and finally
+ * invalidate. First day should be before last day, otherwise the selection won't happen.
+ *
+ * @param first The first day of the range.
+ * @param last The last day in the range.
+ * @see CalendarPagerAdapter#setDateSelected(CalendarDay, boolean)
+ */
+ public void selectRange(final CalendarDay first, final CalendarDay last) {
+ selectedDates.clear();
+
+ // Copy to start from the first day and increment
+ LocalDate temp = LocalDate.of(first.getYear(), first.getMonth(), first.getDay());
- // Copy to start from the first day and increment
- LocalDate temp = LocalDate.of(first.getYear(), first.getMonth(), first.getDay());
+ // for comparison
+ final LocalDate end = last.getDate();
- // for comparison
- final LocalDate end = last.getDate();
+ while (temp.isBefore(end) || temp.equals(end)) {
+ selectedDates.add(CalendarDay.from(temp));
+ temp = temp.plusDays(1);
+ }
- while( temp.isBefore(end) || temp.equals(end) ) {
- selectedDates.add(CalendarDay.from(temp));
- temp = temp.plusDays(1);
+ invalidateSelectedDates();
}
- invalidateSelectedDates();
- }
+ private void invalidateSelectedDates() {
+ validateSelectedDates();
+ for (V pagerView : currentViews) {
+ pagerView.setSelectedDates(selectedDates);
+ }
+ }
- private void invalidateSelectedDates() {
- validateSelectedDates();
- for (V pagerView : currentViews) {
- pagerView.setSelectedDates(selectedDates);
+ private void validateSelectedDates() {
+ for (int i = 0; i < selectedDates.size(); i++) {
+ CalendarDay date = selectedDates.get(i);
+
+ if ((minDate != null && minDate.isAfter(date)) || (maxDate != null
+ && maxDate.isBefore(date))) {
+ selectedDates.remove(i);
+ mcv.onDateUnselected(date);
+ i -= 1;
+ }
+ }
}
- }
- private void validateSelectedDates() {
- for (int i = 0; i < selectedDates.size(); i++) {
- CalendarDay date = selectedDates.get(i);
+ public CalendarDay getItem(int position) {
+ return rangeIndex.getItem(position);
+ }
- if ((minDate != null && minDate.isAfter(date)) || (maxDate != null
- && maxDate.isBefore(date))) {
- selectedDates.remove(i);
- mcv.onDateUnselected(date);
- i -= 1;
- }
+ @NonNull
+ public List getSelectedDates() {
+ return Collections.unmodifiableList(selectedDates);
}
- }
- public CalendarDay getItem(int position) {
- return rangeIndex.getItem(position);
- }
+ protected int getDateTextAppearance() {
+ return dateTextAppearance == null ? 0 : dateTextAppearance;
+ }
- @NonNull
- public List getSelectedDates() {
- return Collections.unmodifiableList(selectedDates);
- }
+ public void setDateTextAppearance(int taId) {
+ if (taId == 0) {
+ return;
+ }
+ this.dateTextAppearance = taId;
+ for (V pagerView : currentViews) {
+ pagerView.setDateTextAppearance(taId);
+ }
+ }
- protected int getDateTextAppearance() {
- return dateTextAppearance == null ? 0 : dateTextAppearance;
- }
+ protected int getWeekDayTextAppearance() {
+ return weekDayTextAppearance == null ? 0 : weekDayTextAppearance;
+ }
- protected int getWeekDayTextAppearance() {
- return weekDayTextAppearance == null ? 0 : weekDayTextAppearance;
- }
+ public void setWeekDayTextAppearance(int taId) {
+ if (taId == 0) {
+ return;
+ }
+ this.weekDayTextAppearance = taId;
+ for (V pagerView : currentViews) {
+ pagerView.setWeekDayTextAppearance(taId);
+ }
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerView.java
index f3a4fa9a..909137f1 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CalendarPagerView.java
@@ -1,18 +1,21 @@
package com.prolificinteractive.materialcalendarview;
import android.os.Build;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+
import com.prolificinteractive.materialcalendarview.MaterialCalendarView.ShowOtherDates;
import com.prolificinteractive.materialcalendarview.format.DayFormatter;
import com.prolificinteractive.materialcalendarview.format.WeekDayFormatter;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
import org.threeten.bp.temporal.TemporalField;
@@ -22,348 +25,348 @@
import static com.prolificinteractive.materialcalendarview.MaterialCalendarView.showOtherMonths;
abstract class CalendarPagerView extends ViewGroup
- implements View.OnClickListener, View.OnLongClickListener {
-
- protected static final int DEFAULT_DAYS_IN_WEEK = 7;
- protected static final int DEFAULT_MAX_WEEKS = 6;
- protected static final int DAY_NAMES_ROW = 1;
-
- private final ArrayList weekDayViews = new ArrayList<>();
- private final ArrayList decoratorResults = new ArrayList<>();
- private final DayOfWeek firstDayOfWeek;
- @ShowOtherDates protected int showOtherDates = SHOW_DEFAULTS;
- private MaterialCalendarView mcv;
- private CalendarDay firstViewDay;
- private CalendarDay minDate = null;
- private CalendarDay maxDate = null;
- protected boolean showWeekDays;
-
- private final Collection dayViews = new ArrayList<>();
-
- public CalendarPagerView(
- @NonNull MaterialCalendarView view,
- CalendarDay firstViewDay,
- DayOfWeek firstDayOfWeek,
- boolean showWeekDays) {
- super(view.getContext());
-
- this.mcv = view;
- this.firstViewDay = firstViewDay;
- this.firstDayOfWeek = firstDayOfWeek;
- this.showWeekDays = showWeekDays;
-
- setClipChildren(false);
- setClipToPadding(false);
-
- if (showWeekDays) {
- buildWeekDays(resetAndGetWorkingCalendar());
- }
- buildDayViews(dayViews, resetAndGetWorkingCalendar());
- }
+ implements View.OnClickListener, View.OnLongClickListener {
+
+ protected static final int DEFAULT_DAYS_IN_WEEK = 7;
+ protected static final int DEFAULT_MAX_WEEKS = 6;
+ protected static final int DAY_NAMES_ROW = 1;
+
+ private final ArrayList weekDayViews = new ArrayList<>();
+ private final ArrayList decoratorResults = new ArrayList<>();
+ private final DayOfWeek firstDayOfWeek;
+ private final Collection dayViews = new ArrayList<>();
+ @ShowOtherDates
+ protected int showOtherDates = SHOW_DEFAULTS;
+ protected boolean showWeekDays;
+ private MaterialCalendarView mcv;
+ private CalendarDay firstViewDay;
+ private CalendarDay minDate = null;
+ private CalendarDay maxDate = null;
+
+ public CalendarPagerView(
+ @NonNull MaterialCalendarView view,
+ CalendarDay firstViewDay,
+ DayOfWeek firstDayOfWeek,
+ boolean showWeekDays) {
+ super(view.getContext());
+
+ this.mcv = view;
+ this.firstViewDay = firstViewDay;
+ this.firstDayOfWeek = firstDayOfWeek;
+ this.showWeekDays = showWeekDays;
+
+ setClipChildren(false);
+ setClipToPadding(false);
+
+ if (showWeekDays) {
+ buildWeekDays(resetAndGetWorkingCalendar());
+ }
+ buildDayViews(dayViews, resetAndGetWorkingCalendar());
+ }
+
+ private void buildWeekDays(LocalDate calendar) {
+ LocalDate local = calendar;
+ for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
+ WeekDayView weekDayView = new WeekDayView(getContext(), local.getDayOfWeek());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ weekDayView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+ weekDayViews.add(weekDayView);
+ addView(weekDayView);
+ local = local.plusDays(1);
+ }
+ }
- private void buildWeekDays(LocalDate calendar) {
- LocalDate local = calendar;
- for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
- WeekDayView weekDayView = new WeekDayView(getContext(), local.getDayOfWeek());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- weekDayView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- }
- weekDayViews.add(weekDayView);
- addView(weekDayView);
- local = local.plusDays(1);
- }
- }
-
- protected void addDayView(Collection dayViews, LocalDate temp) {
- CalendarDay day = CalendarDay.from(temp);
- DayView dayView = new DayView(getContext(), day);
- dayView.setOnClickListener(this);
- dayView.setOnLongClickListener(this);
- dayViews.add(dayView);
- addView(dayView, new LayoutParams());
- }
-
- protected LocalDate resetAndGetWorkingCalendar() {
- final TemporalField firstDayOfWeek = WeekFields.of(this.firstDayOfWeek, 1).dayOfWeek();
- final LocalDate temp = getFirstViewDay().getDate().with(firstDayOfWeek, 1);
- int dow = temp.getDayOfWeek().getValue();
- int delta = getFirstDayOfWeek().getValue() - dow;
- //If the delta is positive, we want to remove a week
- boolean removeRow = showOtherMonths(showOtherDates) ? delta >= 0 : delta > 0;
- if (removeRow) {
- delta -= DEFAULT_DAYS_IN_WEEK;
- }
- return temp.plusDays(delta);
- }
-
- protected DayOfWeek getFirstDayOfWeek() {
- return firstDayOfWeek;
- }
-
- protected abstract void buildDayViews(Collection dayViews, LocalDate calendar);
-
- protected abstract boolean isDayEnabled(CalendarDay day);
-
- void setDayViewDecorators(List results) {
- this.decoratorResults.clear();
- if (results != null) {
- this.decoratorResults.addAll(results);
- }
- invalidateDecorators();
- }
-
- public void setWeekDayTextAppearance(int taId) {
- for (WeekDayView weekDayView : weekDayViews) {
- weekDayView.setTextAppearance(getContext(), taId);
- }
- }
-
- public void setDateTextAppearance(int taId) {
- for (DayView dayView : dayViews) {
- dayView.setTextAppearance(getContext(), taId);
- }
- }
-
- public void setShowOtherDates(@ShowOtherDates int showFlags) {
- this.showOtherDates = showFlags;
- updateUi();
- }
-
- public void setSelectionEnabled(boolean selectionEnabled) {
- for (DayView dayView : dayViews) {
- dayView.setOnClickListener(selectionEnabled ? this : null);
- dayView.setClickable(selectionEnabled);
- }
- }
-
- public void setSelectionColor(int color) {
- for (DayView dayView : dayViews) {
- dayView.setSelectionColor(color);
- }
- }
-
- public void setWeekDayFormatter(WeekDayFormatter formatter) {
- for (WeekDayView dayView : weekDayViews) {
- dayView.setWeekDayFormatter(formatter);
- }
- }
-
- public void setDayFormatter(DayFormatter formatter) {
- for (DayView dayView : dayViews) {
- dayView.setDayFormatter(formatter);
+ protected void addDayView(Collection dayViews, LocalDate temp) {
+ CalendarDay day = CalendarDay.from(temp);
+ DayView dayView = new DayView(getContext(), day);
+ dayView.setOnClickListener(this);
+ dayView.setOnLongClickListener(this);
+ dayViews.add(dayView);
+ addView(dayView, new LayoutParams());
}
- }
-
- public void setDayFormatterContentDescription(DayFormatter formatter) {
- for (DayView dayView : dayViews) {
- dayView.setDayFormatterContentDescription(formatter);
- }
- }
-
- public void setMinimumDate(CalendarDay minDate) {
- this.minDate = minDate;
- updateUi();
- }
-
- public void setMaximumDate(CalendarDay maxDate) {
- this.maxDate = maxDate;
- updateUi();
- }
- public void setSelectedDates(Collection dates) {
- for (DayView dayView : dayViews) {
- CalendarDay day = dayView.getDate();
- dayView.setChecked(dates != null && dates.contains(day));
+ protected LocalDate resetAndGetWorkingCalendar() {
+ final TemporalField firstDayOfWeek = WeekFields.of(this.firstDayOfWeek, 1).dayOfWeek();
+ final LocalDate temp = getFirstViewDay().getDate().with(firstDayOfWeek, 1);
+ int dow = temp.getDayOfWeek().getValue();
+ int delta = getFirstDayOfWeek().getValue() - dow;
+ //If the delta is positive, we want to remove a week
+ boolean removeRow = showOtherMonths(showOtherDates) ? delta >= 0 : delta > 0;
+ if (removeRow) {
+ delta -= DEFAULT_DAYS_IN_WEEK;
+ }
+ return temp.plusDays(delta);
}
- postInvalidate();
- }
- protected void updateUi() {
- for (DayView dayView : dayViews) {
- CalendarDay day = dayView.getDate();
- dayView.setupSelection(showOtherDates, day.isInRange(minDate, maxDate), isDayEnabled(day));
+ protected DayOfWeek getFirstDayOfWeek() {
+ return firstDayOfWeek;
}
- postInvalidate();
- }
- protected void invalidateDecorators() {
- final DayViewFacade facadeAccumulator = new DayViewFacade();
- for (DayView dayView : dayViews) {
- facadeAccumulator.reset();
- for (DecoratorResult result : decoratorResults) {
- if (result.decorator.shouldDecorate(dayView.getDate())) {
- result.result.applyTo(facadeAccumulator);
+ protected abstract void buildDayViews(Collection dayViews, LocalDate calendar);
+
+ protected abstract boolean isDayEnabled(CalendarDay day);
+
+ void setDayViewDecorators(List results) {
+ this.decoratorResults.clear();
+ if (results != null) {
+ this.decoratorResults.addAll(results);
}
- }
- dayView.applyFacade(facadeAccumulator);
- }
- }
-
- @Override
- public void onClick(final View v) {
- if (v instanceof DayView) {
- final DayView dayView = (DayView) v;
- mcv.onDateClicked(dayView);
- }
- }
-
- @Override
- public boolean onLongClick(final View v) {
- if (v instanceof DayView) {
- final DayView dayView = (DayView) v;
- mcv.onDateLongClicked(dayView);
- return true;
- }
- return false;
- }
-
- /*
- * Custom ViewGroup Code
- */
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected LayoutParams generateDefaultLayoutParams() {
- return new LayoutParams();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- final int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
- final int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
- final int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
- final int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
-
- //We expect to be somewhere inside a MaterialCalendarView, which should measure EXACTLY
- if (specHeightMode == MeasureSpec.UNSPECIFIED || specWidthMode == MeasureSpec.UNSPECIFIED) {
- throw new IllegalStateException("CalendarPagerView should never be left to decide it's size");
- }
-
- //The spec width should be a correct multiple
- final int measureTileWidth = specWidthSize / DEFAULT_DAYS_IN_WEEK;
- final int measureTileHeight = specHeightSize / getRows();
-
- //Just use the spec sizes
- setMeasuredDimension(specWidthSize, specHeightSize);
-
- int count = getChildCount();
-
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
-
- int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
- measureTileWidth,
- MeasureSpec.EXACTLY
- );
-
- int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
- measureTileHeight,
- MeasureSpec.EXACTLY
- );
-
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
- }
- }
-
- /**
- * Return the number of rows to display per page
- */
- protected abstract int getRows();
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final int parentWidth = getWidth();
- final int count = getChildCount();
- final int parentLeft = 0;
- final int parentRight = parentWidth;
-
- int childTop = 0;
- int childLeft = parentLeft;
- int childRight = parentRight;
-
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
-
- final int width = child.getMeasuredWidth();
- final int height = child.getMeasuredHeight();
-
- if (LocalUtils.isRTL()) {
- child.layout(childRight - width, childTop, childRight, childTop + height);
- childRight -= width;
- } else {
- child.layout(childLeft, childTop, childLeft + width, childTop + height);
- childLeft += width;
- }
-
- //We should warp every so many children
- if (i % DEFAULT_DAYS_IN_WEEK == (DEFAULT_DAYS_IN_WEEK - 1)) {
- childLeft = parentLeft;
- childRight = parentRight;
- childTop += height;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public LayoutParams generateLayoutParams(AttributeSet attrs) {
- return new LayoutParams();
- }
-
- @Override
- public boolean shouldDelayChildPressedState() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
- return p instanceof LayoutParams;
- }
-
- @Override
- protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
- return new LayoutParams();
- }
-
- @Override
- public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- event.setClassName(CalendarPagerView.class.getName());
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.setClassName(CalendarPagerView.class.getName());
- }
-
- protected CalendarDay getFirstViewDay() {
- return firstViewDay;
- }
-
- /**
- * Simple layout params class for MonthView, since every child is the same size
- */
- protected static class LayoutParams extends MarginLayoutParams {
+ invalidateDecorators();
+ }
+
+ public void setWeekDayTextAppearance(int taId) {
+ for (WeekDayView weekDayView : weekDayViews) {
+ weekDayView.setTextAppearance(getContext(), taId);
+ }
+ }
+
+ public void setDateTextAppearance(int taId) {
+ for (DayView dayView : dayViews) {
+ dayView.setTextAppearance(getContext(), taId);
+ }
+ }
+
+ public void setShowOtherDates(@ShowOtherDates int showFlags) {
+ this.showOtherDates = showFlags;
+ updateUi();
+ }
+
+ public void setSelectionEnabled(boolean selectionEnabled) {
+ for (DayView dayView : dayViews) {
+ dayView.setOnClickListener(selectionEnabled ? this : null);
+ dayView.setClickable(selectionEnabled);
+ }
+ }
+
+ public void setSelectionColor(int color) {
+ for (DayView dayView : dayViews) {
+ dayView.setSelectionColor(color);
+ }
+ }
+
+ public void setWeekDayFormatter(WeekDayFormatter formatter) {
+ for (WeekDayView dayView : weekDayViews) {
+ dayView.setWeekDayFormatter(formatter);
+ }
+ }
+
+ public void setDayFormatter(DayFormatter formatter) {
+ for (DayView dayView : dayViews) {
+ dayView.setDayFormatter(formatter);
+ }
+ }
+
+ public void setDayFormatterContentDescription(DayFormatter formatter) {
+ for (DayView dayView : dayViews) {
+ dayView.setDayFormatterContentDescription(formatter);
+ }
+ }
+
+ public void setMinimumDate(CalendarDay minDate) {
+ this.minDate = minDate;
+ updateUi();
+ }
+
+ public void setMaximumDate(CalendarDay maxDate) {
+ this.maxDate = maxDate;
+ updateUi();
+ }
+
+ public void setSelectedDates(Collection dates) {
+ for (DayView dayView : dayViews) {
+ CalendarDay day = dayView.getDate();
+ dayView.setChecked(dates != null && dates.contains(day));
+ }
+ postInvalidate();
+ }
+
+ protected void updateUi() {
+ for (DayView dayView : dayViews) {
+ CalendarDay day = dayView.getDate();
+ dayView.setupSelection(showOtherDates, day.isInRange(minDate, maxDate), isDayEnabled(day));
+ }
+ postInvalidate();
+ }
+
+ protected void invalidateDecorators() {
+ final DayViewFacade facadeAccumulator = new DayViewFacade();
+ for (DayView dayView : dayViews) {
+ facadeAccumulator.reset();
+ for (DecoratorResult result : decoratorResults) {
+ if (result.decorator.shouldDecorate(dayView.getDate())) {
+ result.result.applyTo(facadeAccumulator);
+ }
+ }
+ dayView.applyFacade(facadeAccumulator);
+ }
+ }
+
+ @Override
+ public void onClick(final View v) {
+ if (v instanceof DayView) {
+ final DayView dayView = (DayView) v;
+ mcv.onDateClicked(dayView);
+ }
+ }
+
+ @Override
+ public boolean onLongClick(final View v) {
+ if (v instanceof DayView) {
+ final DayView dayView = (DayView) v;
+ mcv.onDateLongClicked(dayView);
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * Custom ViewGroup Code
+ */
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ final int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
+ final int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+ //We expect to be somewhere inside a MaterialCalendarView, which should measure EXACTLY
+ if (specHeightMode == MeasureSpec.UNSPECIFIED || specWidthMode == MeasureSpec.UNSPECIFIED) {
+ throw new IllegalStateException("CalendarPagerView should never be left to decide it's size");
+ }
+
+ //The spec width should be a correct multiple
+ final int measureTileWidth = specWidthSize / DEFAULT_DAYS_IN_WEEK;
+ final int measureTileHeight = specHeightSize / getRows();
+
+ //Just use the spec sizes
+ setMeasuredDimension(specWidthSize, specHeightSize);
+
+ int count = getChildCount();
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ measureTileWidth,
+ MeasureSpec.EXACTLY
+ );
+
+ int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ measureTileHeight,
+ MeasureSpec.EXACTLY
+ );
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+
+ /**
+ * Return the number of rows to display per page
+ */
+ protected abstract int getRows();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ final int parentWidth = getWidth();
+ final int count = getChildCount();
+ final int parentLeft = 0;
+ final int parentRight = parentWidth;
+
+ int childTop = 0;
+ int childLeft = parentLeft;
+ int childRight = parentRight;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+
+ final int width = child.getMeasuredWidth();
+ final int height = child.getMeasuredHeight();
+
+ if (LocalUtils.isRTL()) {
+ child.layout(childRight - width, childTop, childRight, childTop + height);
+ childRight -= width;
+ } else {
+ child.layout(childLeft, childTop, childLeft + width, childTop + height);
+ childLeft += width;
+ }
+
+ //We should warp every so many children
+ if (i % DEFAULT_DAYS_IN_WEEK == (DEFAULT_DAYS_IN_WEEK - 1)) {
+ childLeft = parentLeft;
+ childRight = parentRight;
+ childTop += height;
+ }
+ }
+ }
/**
* {@inheritDoc}
*/
- public LayoutParams() {
- super(WRAP_CONTENT, WRAP_CONTENT);
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams();
+ }
+
+ @Override
+ public boolean shouldDelayChildPressedState() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams();
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(CalendarPagerView.class.getName());
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(CalendarPagerView.class.getName());
+ }
+
+ protected CalendarDay getFirstViewDay() {
+ return firstViewDay;
+ }
+
+ /**
+ * Simple layout params class for MonthView, since every child is the same size
+ */
+ protected static class LayoutParams extends MarginLayoutParams {
+
+ /**
+ * {@inheritDoc}
+ */
+ public LayoutParams() {
+ super(WRAP_CONTENT, WRAP_CONTENT);
+ }
}
- }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CurrentDayDecorator.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CurrentDayDecorator.java
new file mode 100644
index 00000000..64ec68d6
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CurrentDayDecorator.java
@@ -0,0 +1,41 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.text.style.ForegroundColorSpan;
+
+import androidx.core.content.ContextCompat;
+
+public class CurrentDayDecorator implements DayViewDecorator {
+
+ private final Drawable selectionDrawable;
+ private Drawable drawable;
+ private boolean flag;
+
+ private CalendarDay currentDay = CalendarDay.today();
+
+ public CurrentDayDecorator(Activity context, boolean flag) {
+ drawable = ContextCompat.getDrawable(context, R.drawable.gray_circle);
+ selectionDrawable = ContextCompat.getDrawable(context, R.drawable.calendar_selector);
+ this.flag = flag;
+ }
+
+ @Override
+ public boolean shouldDecorate(CalendarDay day) {
+ return day.equals(currentDay);
+ }
+
+ @Override
+ public void decorate(DayViewFacade view) {
+ if (flag) {
+ view.addSpan(new ForegroundColorSpan(Color.WHITE));
+ view.setSelectionDrawable(selectionDrawable);
+
+ } else {
+ view.addSpan(new ForegroundColorSpan(Color.BLACK));
+ view.setSelectionDrawable(drawable);
+
+ }
+ }
+}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/CustomMultipleDotSpan.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/CustomMultipleDotSpan.java
new file mode 100644
index 00000000..bb91102d
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/CustomMultipleDotSpan.java
@@ -0,0 +1,61 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.app.Activity;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.style.LineBackgroundSpan;
+
+public class CustomMultipleDotSpan implements LineBackgroundSpan {
+
+ private final float radius;
+ private int[] color = new int[0];
+ private Activity context;
+
+
+ public CustomMultipleDotSpan() {
+ this.radius = 5;
+ this.color[0] = 5;
+ }
+
+
+ public CustomMultipleDotSpan(int color) {
+ this.radius = 5;
+ this.color[0] = 0;
+ }
+
+
+ public CustomMultipleDotSpan(float radius) {
+ this.radius = radius;
+ this.color[0] = 0;
+ }
+
+
+ public CustomMultipleDotSpan(Activity context, float radius, int[] color) {
+ this.radius = radius;
+ this.color = color;
+ this.context = context;
+ }
+
+ @Override
+ public void drawBackground(
+ Canvas canvas, Paint paint,
+ int left, int right, int top, int baseline, int bottom,
+ CharSequence charSequence,
+ int start, int end, int lineNum
+ ) {
+
+ int total = color.length > 5 ? 5 : color.length;
+ int leftMost = (total - 1) * -10;
+
+ for (int i = 0; i < total; i++) {
+ int oldColor = paint.getColor();
+ if (color[i] != 0) {
+ paint.setColor(color[i]);
+ }
+ int extraMarginDots = context.getResources().getDimensionPixelSize(R.dimen._5sdp) + 3;
+ canvas.drawCircle((left + right) / 2 - leftMost, bottom + extraMarginDots, radius - 2, paint);
+ paint.setColor(oldColor);
+ leftMost = leftMost + 20;
+ }
+ }
+}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/DateRangeIndex.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/DateRangeIndex.java
index ff1c3811..ca2f888a 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/DateRangeIndex.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/DateRangeIndex.java
@@ -6,18 +6,18 @@
*/
interface DateRangeIndex {
- /**
- * Count of pages displayed between 2 dates.
- */
- int getCount();
+ /**
+ * Count of pages displayed between 2 dates.
+ */
+ int getCount();
- /**
- * Index of the page where the date is displayed.
- */
- int indexOf(CalendarDay day);
+ /**
+ * Index of the page where the date is displayed.
+ */
+ int indexOf(CalendarDay day);
- /**
- * Get the first date at the position within the index.
- */
- CalendarDay getItem(int position);
+ /**
+ * Get the first date at the position within the index.
+ */
+ CalendarDay getItem(int position);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayView.java
index 675e5f94..ca12fae4 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayView.java
@@ -6,6 +6,9 @@
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
+
+import com.prolificinteractive.materialcalendarview.format.DateFormatDayFormatter;
+
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
@@ -13,14 +16,16 @@
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Build;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.AppCompatCheckedTextView;
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatCheckedTextView;
import android.text.SpannableString;
import android.text.Spanned;
import android.view.Gravity;
import android.view.View;
+
import com.prolificinteractive.materialcalendarview.MaterialCalendarView.ShowOtherDates;
import com.prolificinteractive.materialcalendarview.format.DayFormatter;
+
import java.util.List;
import static com.prolificinteractive.materialcalendarview.MaterialCalendarView.showDecoratedDisabled;
@@ -30,276 +35,274 @@
/**
* Display one day of a {@linkplain MaterialCalendarView}
*/
-@SuppressLint("ViewConstructor") class DayView extends AppCompatCheckedTextView {
+@SuppressLint("ViewConstructor")
+class DayView extends AppCompatCheckedTextView {
+
+ private final int fadeTime;
+ private final Rect tempRect = new Rect();
+ private final Rect circleDrawableRect = new Rect();
+ private CalendarDay date;
+ private int selectionColor = Color.GRAY;
+ private Drawable customBackground = null;
+ private Drawable selectionDrawable;
+ private Drawable mCircleDrawable;
+ private DayFormatter formatter = DateFormatDayFormatter.getInstance();
+ private DayFormatter contentDescriptionFormatter = formatter;
+ private boolean isInRange = true;
+ private boolean isInMonth = true;
+ private boolean isDecoratedDisabled = false;
+ @ShowOtherDates
+ private int showOtherDates = MaterialCalendarView.SHOW_DEFAULTS;
+
+ public DayView(Context context, CalendarDay day) {
+ super(context);
+
+ fadeTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
+
+ setSelectionColor(this.selectionColor);
+
+ setGravity(Gravity.CENTER);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ setTextAlignment(TEXT_ALIGNMENT_CENTER);
+ }
+
+ setDay(day);
+ }
- private CalendarDay date;
- private int selectionColor = Color.GRAY;
+ private static Drawable generateBackground(int color, int fadeTime, Rect bounds) {
+ StateListDrawable drawable = new StateListDrawable();
+ drawable.setExitFadeDuration(fadeTime);
+ drawable.addState(new int[]{android.R.attr.state_checked}, generateCircleDrawable(color));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ drawable.addState(
+ new int[]{android.R.attr.state_pressed},
+ generateRippleDrawable(color, bounds)
+ );
+ } else {
+ drawable.addState(new int[]{android.R.attr.state_pressed}, generateCircleDrawable(color));
+ }
+
+ drawable.addState(new int[]{}, generateCircleDrawable(Color.TRANSPARENT));
+
+ return drawable;
+ }
- private final int fadeTime;
- private Drawable customBackground = null;
- private Drawable selectionDrawable;
- private Drawable mCircleDrawable;
- private DayFormatter formatter = DayFormatter.DEFAULT;
- private DayFormatter contentDescriptionFormatter = formatter;
+ private static Drawable generateCircleDrawable(final int color) {
+ ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
+ drawable.getPaint().setColor(color);
+ return drawable;
+ }
- private boolean isInRange = true;
- private boolean isInMonth = true;
- private boolean isDecoratedDisabled = false;
- @ShowOtherDates
- private int showOtherDates = MaterialCalendarView.SHOW_DEFAULTS;
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private static Drawable generateRippleDrawable(final int color, Rect bounds) {
+ ColorStateList list = ColorStateList.valueOf(color);
+ Drawable mask = generateCircleDrawable(Color.WHITE);
+ RippleDrawable rippleDrawable = new RippleDrawable(list, null, mask);
+ // API 21
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
+ rippleDrawable.setBounds(bounds);
+ }
+
+ // API 22. Technically harmless to leave on for API 21 and 23, but not worth risking for 23+
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1) {
+ int center = (bounds.left + bounds.right) / 2;
+ rippleDrawable.setHotspotBounds(center, bounds.top, center, bounds.bottom);
+ }
+
+ return rippleDrawable;
+ }
- public DayView(Context context, CalendarDay day) {
- super(context);
+ public void setDay(CalendarDay date) {
+ this.date = date;
+ setText(getLabel());
+ }
- fadeTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
+ /**
+ * Set the new label formatter and reformat the current label. This preserves current spans.
+ *
+ * @param formatter new label formatter
+ */
+ public void setDayFormatter(DayFormatter formatter) {
+ this.contentDescriptionFormatter = contentDescriptionFormatter == this.formatter ?
+ formatter : contentDescriptionFormatter;
+ this.formatter = formatter == null ? DateFormatDayFormatter.getInstance() : formatter;
+ CharSequence currentLabel = getText();
+ Object[] spans = null;
+ if (currentLabel instanceof Spanned) {
+ spans = ((Spanned) currentLabel).getSpans(0, currentLabel.length(), Object.class);
+ }
+ SpannableString newLabel = new SpannableString(getLabel());
+ if (spans != null) {
+ for (Object span : spans) {
+ newLabel.setSpan(span, 0, newLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+ setText(newLabel);
+ }
- setSelectionColor(this.selectionColor);
+ /**
+ * Set the new content description formatter and reformat the current content description.
+ *
+ * @param formatter new content description formatter
+ */
+ public void setDayFormatterContentDescription(DayFormatter formatter) {
+ this.contentDescriptionFormatter = formatter == null ? this.formatter : formatter;
+ setContentDescription(getContentDescriptionLabel());
+ }
- setGravity(Gravity.CENTER);
+ @NonNull
+ public String getLabel() {
+ return formatter.format(date);
+ }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- setTextAlignment(TEXT_ALIGNMENT_CENTER);
+ @NonNull
+ public String getContentDescriptionLabel() {
+ return contentDescriptionFormatter == null ? formatter.format(date)
+ : contentDescriptionFormatter.format(date);
}
- setDay(day);
- }
-
- public void setDay(CalendarDay date) {
- this.date = date;
- setText(getLabel());
- }
-
- /**
- * Set the new label formatter and reformat the current label. This preserves current spans.
- *
- * @param formatter new label formatter
- */
- public void setDayFormatter(DayFormatter formatter) {
- this.contentDescriptionFormatter = contentDescriptionFormatter == this.formatter ?
- formatter : contentDescriptionFormatter;
- this.formatter = formatter == null ? DayFormatter.DEFAULT : formatter;
- CharSequence currentLabel = getText();
- Object[] spans = null;
- if (currentLabel instanceof Spanned) {
- spans = ((Spanned) currentLabel).getSpans(0, currentLabel.length(), Object.class);
+ public void setSelectionColor(int color) {
+ this.selectionColor = color;
+ regenerateBackground();
}
- SpannableString newLabel = new SpannableString(getLabel());
- if (spans != null) {
- for (Object span : spans) {
- newLabel.setSpan(span, 0, newLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
+
+ /**
+ * @param drawable custom selection drawable
+ */
+ public void setSelectionDrawable(Drawable drawable) {
+ if (drawable == null) {
+ this.selectionDrawable = null;
+ } else {
+ this.selectionDrawable = drawable.getConstantState().newDrawable(getResources());
+ }
+ regenerateBackground();
}
- setText(newLabel);
- }
-
- /**
- * Set the new content description formatter and reformat the current content description.
- *
- * @param formatter new content description formatter
- */
- public void setDayFormatterContentDescription(DayFormatter formatter) {
- this.contentDescriptionFormatter = formatter == null ? this.formatter : formatter;
- setContentDescription(getContentDescriptionLabel());
- }
-
- @NonNull
- public String getLabel() {
- return formatter.format(date);
- }
-
- @NonNull
- public String getContentDescriptionLabel() {
- return contentDescriptionFormatter == null ? formatter.format(date)
- : contentDescriptionFormatter.format(date);
- }
-
- public void setSelectionColor(int color) {
- this.selectionColor = color;
- regenerateBackground();
- }
-
- /**
- * @param drawable custom selection drawable
- */
- public void setSelectionDrawable(Drawable drawable) {
- if (drawable == null) {
- this.selectionDrawable = null;
- } else {
- this.selectionDrawable = drawable.getConstantState().newDrawable(getResources());
+
+ /**
+ * @param drawable background to draw behind everything else
+ */
+ public void setCustomBackground(Drawable drawable) {
+ if (drawable == null) {
+ this.customBackground = null;
+ } else {
+ this.customBackground = drawable.getConstantState().newDrawable(getResources());
+ }
+ invalidate();
}
- regenerateBackground();
- }
-
- /**
- * @param drawable background to draw behind everything else
- */
- public void setCustomBackground(Drawable drawable) {
- if (drawable == null) {
- this.customBackground = null;
- } else {
- this.customBackground = drawable.getConstantState().newDrawable(getResources());
+
+ public CalendarDay getDate() {
+ return date;
}
- invalidate();
- }
- public CalendarDay getDate() {
- return date;
- }
+ private void setEnabled() {
+ boolean enabled = isInMonth && isInRange && !isDecoratedDisabled;
+ super.setEnabled(isInRange && !isDecoratedDisabled);
- private void setEnabled() {
- boolean enabled = isInMonth && isInRange && !isDecoratedDisabled;
- super.setEnabled(isInRange && !isDecoratedDisabled);
+ boolean showOtherMonths = showOtherMonths(showOtherDates);
+ boolean showOutOfRange = showOutOfRange(showOtherDates) || showOtherMonths;
+ boolean showDecoratedDisabled = showDecoratedDisabled(showOtherDates);
- boolean showOtherMonths = showOtherMonths(showOtherDates);
- boolean showOutOfRange = showOutOfRange(showOtherDates) || showOtherMonths;
- boolean showDecoratedDisabled = showDecoratedDisabled(showOtherDates);
+ boolean shouldBeVisible = enabled;
- boolean shouldBeVisible = enabled;
+ if (!isInMonth && showOtherMonths) {
+ shouldBeVisible = true;
+ }
- if (!isInMonth && showOtherMonths) {
- shouldBeVisible = true;
- }
+ if (!isInRange && showOutOfRange) {
+ shouldBeVisible |= isInMonth;
+ }
- if (!isInRange && showOutOfRange) {
- shouldBeVisible |= isInMonth;
- }
+ if (isDecoratedDisabled && showDecoratedDisabled) {
+ shouldBeVisible |= isInMonth && isInRange;
+ }
- if (isDecoratedDisabled && showDecoratedDisabled) {
- shouldBeVisible |= isInMonth && isInRange;
+ if (!isInMonth && shouldBeVisible) {
+ setTextColor(getTextColors().getColorForState(
+ new int[]{-android.R.attr.state_enabled}, Color.GRAY));
+ }
+ setVisibility(shouldBeVisible ? View.VISIBLE : View.INVISIBLE);
}
- if (!isInMonth && shouldBeVisible) {
- setTextColor(getTextColors().getColorForState(
- new int[] { -android.R.attr.state_enabled }, Color.GRAY));
- }
- setVisibility(shouldBeVisible ? View.VISIBLE : View.INVISIBLE);
- }
-
- protected void setupSelection(
- @ShowOtherDates int showOtherDates,
- boolean inRange,
- boolean inMonth) {
- this.showOtherDates = showOtherDates;
- this.isInMonth = inMonth;
- this.isInRange = inRange;
- setEnabled();
- }
-
- private final Rect tempRect = new Rect();
- private final Rect circleDrawableRect = new Rect();
-
- @Override
- protected void onDraw(@NonNull Canvas canvas) {
- if (customBackground != null) {
- customBackground.setBounds(tempRect);
- customBackground.setState(getDrawableState());
- customBackground.draw(canvas);
+ protected void setupSelection(
+ @ShowOtherDates int showOtherDates,
+ boolean inRange,
+ boolean inMonth) {
+ this.showOtherDates = showOtherDates;
+ this.isInMonth = inMonth;
+ this.isInRange = inRange;
+ setEnabled();
}
- mCircleDrawable.setBounds(circleDrawableRect);
+ @Override
+ protected void onDraw(@NonNull Canvas canvas) {
+ if (customBackground != null) {
+ customBackground.setBounds(tempRect);
+ customBackground.setState(getDrawableState());
+ customBackground.draw(canvas);
+ }
- super.onDraw(canvas);
- }
+ mCircleDrawable.setBounds(circleDrawableRect);
- private void regenerateBackground() {
- if (selectionDrawable != null) {
- setBackgroundDrawable(selectionDrawable);
- } else {
- mCircleDrawable = generateBackground(selectionColor, fadeTime, circleDrawableRect);
- setBackgroundDrawable(mCircleDrawable);
- }
- }
-
- private static Drawable generateBackground(int color, int fadeTime, Rect bounds) {
- StateListDrawable drawable = new StateListDrawable();
- drawable.setExitFadeDuration(fadeTime);
- drawable.addState(new int[] { android.R.attr.state_checked }, generateCircleDrawable(color));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- drawable.addState(
- new int[] { android.R.attr.state_pressed },
- generateRippleDrawable(color, bounds)
- );
- } else {
- drawable.addState(new int[] { android.R.attr.state_pressed }, generateCircleDrawable(color));
+ super.onDraw(canvas);
}
- drawable.addState(new int[] { }, generateCircleDrawable(Color.TRANSPARENT));
-
- return drawable;
- }
-
- private static Drawable generateCircleDrawable(final int color) {
- ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
- drawable.getPaint().setColor(color);
- return drawable;
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private static Drawable generateRippleDrawable(final int color, Rect bounds) {
- ColorStateList list = ColorStateList.valueOf(color);
- Drawable mask = generateCircleDrawable(Color.WHITE);
- RippleDrawable rippleDrawable = new RippleDrawable(list, null, mask);
- // API 21
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
- rippleDrawable.setBounds(bounds);
+ private void regenerateBackground() {
+ if (selectionDrawable != null) {
+ setBackgroundDrawable(selectionDrawable);
+ } else {
+ mCircleDrawable = generateBackground(selectionColor, fadeTime, circleDrawableRect);
+ setBackgroundDrawable(mCircleDrawable);
+ }
}
- // API 22. Technically harmless to leave on for API 21 and 23, but not worth risking for 23+
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1) {
- int center = (bounds.left + bounds.right) / 2;
- rippleDrawable.setHotspotBounds(center, bounds.top, center, bounds.bottom);
+ /**
+ * @param facade apply the facade to us
+ */
+ void applyFacade(DayViewFacade facade) {
+ this.isDecoratedDisabled = facade.areDaysDisabled();
+ setEnabled();
+
+ setCustomBackground(facade.getBackgroundDrawable());
+ setSelectionDrawable(facade.getSelectionDrawable());
+
+ // Facade has spans
+ List spans = facade.getSpans();
+ if (!spans.isEmpty()) {
+ String label = getLabel();
+ SpannableString formattedLabel = new SpannableString(getLabel());
+ for (DayViewFacade.Span span : spans) {
+ formattedLabel.setSpan(span.span, 0, label.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ setText(formattedLabel);
+ }
+ // Reset in case it was customized previously
+ else {
+ setText(getLabel());
+ }
}
- return rippleDrawable;
- }
-
- /**
- * @param facade apply the facade to us
- */
- void applyFacade(DayViewFacade facade) {
- this.isDecoratedDisabled = facade.areDaysDisabled();
- setEnabled();
-
- setCustomBackground(facade.getBackgroundDrawable());
- setSelectionDrawable(facade.getSelectionDrawable());
-
- // Facade has spans
- List spans = facade.getSpans();
- if (!spans.isEmpty()) {
- String label = getLabel();
- SpannableString formattedLabel = new SpannableString(getLabel());
- for (DayViewFacade.Span span : spans) {
- formattedLabel.setSpan(span.span, 0, label.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- setText(formattedLabel);
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ calculateBounds(right - left, bottom - top);
+ regenerateBackground();
}
- // Reset in case it was customized previously
- else {
- setText(getLabel());
- }
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- calculateBounds(right - left, bottom - top);
- regenerateBackground();
- }
-
- private void calculateBounds(int width, int height) {
- final int radius = Math.min(height, width);
- final int offset = Math.abs(height - width) / 2;
-
- // Lollipop platform bug. Circle drawable offset needs to be half of normal offset
- final int circleOffset =
- Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP ? offset / 2 : offset;
-
- if (width >= height) {
- tempRect.set(offset, 0, radius + offset, height);
- circleDrawableRect.set(circleOffset, 0, radius + circleOffset, height);
- } else {
- tempRect.set(0, offset, width, radius + offset);
- circleDrawableRect.set(0, circleOffset, width, radius + circleOffset);
+
+ private void calculateBounds(int width, int height) {
+ final int radius = Math.min(height, width);
+ final int offset = Math.abs(height - width) / 2;
+
+ // Lollipop platform bug. Circle drawable offset needs to be half of normal offset
+ final int circleOffset =
+ Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP ? offset / 2 : offset;
+
+ if (width >= height) {
+ tempRect.set(offset, 0, radius + offset, height);
+ circleDrawableRect.set(circleOffset, 0, radius + circleOffset, height);
+ } else {
+ tempRect.set(0, offset, width, radius + offset);
+ circleDrawableRect.set(0, circleOffset, width, radius + circleOffset);
+ }
}
- }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewDecorator.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewDecorator.java
index 4b7585c1..e6657816 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewDecorator.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewDecorator.java
@@ -5,18 +5,18 @@
*/
public interface DayViewDecorator {
- /**
- * Determine if a specific day should be decorated
- *
- * @param day {@linkplain CalendarDay} to possibly decorate
- * @return true if this decorator should be applied to the provided day
- */
- boolean shouldDecorate(CalendarDay day);
+ /**
+ * Determine if a specific day should be decorated
+ *
+ * @param day {@linkplain CalendarDay} to possibly decorate
+ * @return true if this decorator should be applied to the provided day
+ */
+ boolean shouldDecorate(CalendarDay day);
- /**
- * Set decoration options onto a facade to be applied to all relevant days
- *
- * @param view View to decorate
- */
- void decorate(DayViewFacade view);
+ /**
+ * Set decoration options onto a facade to be applied to all relevant days
+ *
+ * @param view View to decorate
+ */
+ void decorate(DayViewFacade view);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewFacade.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewFacade.java
index cbffdfec..53df2a21 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewFacade.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/DayViewFacade.java
@@ -1,7 +1,8 @@
package com.prolificinteractive.materialcalendarview;
import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -11,124 +12,123 @@
*/
public class DayViewFacade {
- private boolean isDecorated;
-
- private Drawable backgroundDrawable = null;
- private Drawable selectionDrawable = null;
- private final LinkedList spans = new LinkedList<>();
- private boolean daysDisabled = false;
-
- DayViewFacade() {
- isDecorated = false;
- }
-
- /**
- * Set a drawable to draw behind everything else
- *
- * @param drawable Drawable to draw behind everything
- */
- public void setBackgroundDrawable(@NonNull Drawable drawable) {
- if (drawable == null) {
- throw new IllegalArgumentException("Cannot be null");
+ private final LinkedList spans = new LinkedList<>();
+ private boolean isDecorated;
+ private Drawable backgroundDrawable = null;
+ private Drawable selectionDrawable = null;
+ private boolean daysDisabled = false;
+
+ DayViewFacade() {
+ isDecorated = false;
+ }
+
+ /**
+ * Add a span to the entire text of a day
+ *
+ * @param span text span instance
+ */
+ public void addSpan(@NonNull Object span) {
+ if (spans != null) {
+ this.spans.add(new Span(span));
+ isDecorated = true;
+ }
+ }
+
+ /**
+ *
Set days to be in a disabled state, or re-enabled.
+ *
Note, passing true here will not override minimum and maximum dates, if set.
+ * This will only re-enable disabled dates.
+ *
+ * @param daysDisabled true to disable days, false to re-enable days
+ */
+ public void setDaysDisabled(boolean daysDisabled) {
+ this.daysDisabled = daysDisabled;
+ this.isDecorated = true;
}
- this.backgroundDrawable = drawable;
- isDecorated = true;
- }
-
- /**
- * Set a custom selection drawable
- * TODO: define states that can/should be used in StateListDrawables
- *
- * @param drawable the drawable for selection
- */
- public void setSelectionDrawable(@NonNull Drawable drawable) {
- if (drawable == null) {
- throw new IllegalArgumentException("Cannot be null");
+
+ void reset() {
+ backgroundDrawable = null;
+ selectionDrawable = null;
+ spans.clear();
+ isDecorated = false;
+ daysDisabled = false;
+ }
+
+ /**
+ * Apply things set this to other
+ *
+ * @param other facade to apply our data to
+ */
+ void applyTo(DayViewFacade other) {
+ if (selectionDrawable != null) {
+ other.setSelectionDrawable(selectionDrawable);
+ }
+ if (backgroundDrawable != null) {
+ other.setBackgroundDrawable(backgroundDrawable);
+ }
+ other.spans.addAll(spans);
+ other.isDecorated |= this.isDecorated;
+ other.daysDisabled = daysDisabled;
}
- selectionDrawable = drawable;
- isDecorated = true;
- }
-
- /**
- * Add a span to the entire text of a day
- *
- * @param span text span instance
- */
- public void addSpan(@NonNull Object span) {
- if (spans != null) {
- this.spans.add(new Span(span));
- isDecorated = true;
+
+ boolean isDecorated() {
+ return isDecorated;
}
- }
-
- /**
- *
Set days to be in a disabled state, or re-enabled.
- *
Note, passing true here will not override minimum and maximum dates, if set.
- * This will only re-enable disabled dates.
- *
- * @param daysDisabled true to disable days, false to re-enable days
- */
- public void setDaysDisabled(boolean daysDisabled) {
- this.daysDisabled = daysDisabled;
- this.isDecorated = true;
- }
-
- void reset() {
- backgroundDrawable = null;
- selectionDrawable = null;
- spans.clear();
- isDecorated = false;
- daysDisabled = false;
- }
-
- /**
- * Apply things set this to other
- *
- * @param other facade to apply our data to
- */
- void applyTo(DayViewFacade other) {
- if (selectionDrawable != null) {
- other.setSelectionDrawable(selectionDrawable);
+
+ Drawable getSelectionDrawable() {
+ return selectionDrawable;
}
- if (backgroundDrawable != null) {
- other.setBackgroundDrawable(backgroundDrawable);
+
+ /**
+ * Set a custom selection drawable
+ * TODO: define states that can/should be used in StateListDrawables
+ *
+ * @param drawable the drawable for selection
+ */
+ public void setSelectionDrawable(@NonNull Drawable drawable) {
+ if (drawable == null) {
+ throw new IllegalArgumentException("Cannot be null");
+ }
+ selectionDrawable = drawable;
+ isDecorated = true;
}
- other.spans.addAll(spans);
- other.isDecorated |= this.isDecorated;
- other.daysDisabled = daysDisabled;
- }
-
- boolean isDecorated() {
- return isDecorated;
- }
-
- Drawable getSelectionDrawable() {
- return selectionDrawable;
- }
-
- Drawable getBackgroundDrawable() {
- return backgroundDrawable;
- }
-
- List getSpans() {
- return Collections.unmodifiableList(spans);
- }
-
- /**
- * Are days from this facade disabled
- *
- * @return true if disabled, false if not re-enabled
- */
- public boolean areDaysDisabled() {
- return daysDisabled;
- }
-
- static class Span {
-
- final Object span;
-
- public Span(Object span) {
- this.span = span;
+
+ Drawable getBackgroundDrawable() {
+ return backgroundDrawable;
+ }
+
+ /**
+ * Set a drawable to draw behind everything else
+ *
+ * @param drawable Drawable to draw behind everything
+ */
+ public void setBackgroundDrawable(@NonNull Drawable drawable) {
+ if (drawable == null) {
+ throw new IllegalArgumentException("Cannot be null");
+ }
+ this.backgroundDrawable = drawable;
+ isDecorated = true;
+ }
+
+ List getSpans() {
+ return Collections.unmodifiableList(spans);
+ }
+
+ /**
+ * Are days from this facade disabled
+ *
+ * @return true if disabled, false if not re-enabled
+ */
+ public boolean areDaysDisabled() {
+ return daysDisabled;
+ }
+
+ static class Span {
+
+ final Object span;
+
+ public Span(Object span) {
+ this.span = span;
+ }
}
- }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/DecoratorResult.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/DecoratorResult.java
index 392897f3..d491a955 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/DecoratorResult.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/DecoratorResult.java
@@ -1,11 +1,11 @@
package com.prolificinteractive.materialcalendarview;
class DecoratorResult {
- public final DayViewDecorator decorator;
- public final DayViewFacade result;
+ public final DayViewDecorator decorator;
+ public final DayViewFacade result;
- DecoratorResult(DayViewDecorator decorator, DayViewFacade result) {
- this.decorator = decorator;
- this.result = result;
- }
+ DecoratorResult(DayViewDecorator decorator, DayViewFacade result) {
+ this.decorator = decorator;
+ this.result = result;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/LocalUtils.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/LocalUtils.java
index 19870623..bb995e8f 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/LocalUtils.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/LocalUtils.java
@@ -1,15 +1,17 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.v4.text.TextUtilsCompat;
-import android.support.v4.view.ViewCompat;
+import androidx.core.text.TextUtilsCompat;
+import androidx.core.view.ViewCompat;
+
import java.util.Locale;
class LocalUtils {
- private LocalUtils() { }
+ private LocalUtils() {
+ }
- static boolean isRTL() {
- return TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
- == ViewCompat.LAYOUT_DIRECTION_RTL;
- }
+ static boolean isRTL() {
+ return TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
+ == ViewCompat.LAYOUT_DIRECTION_RTL;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java
index 623b4a69..65a65af6 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java
@@ -9,12 +9,6 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
-import android.support.annotation.ArrayRes;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
@@ -27,11 +21,25 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+
+import androidx.annotation.ArrayRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.viewpager.widget.ViewPager;
+
import com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter;
+import com.prolificinteractive.materialcalendarview.format.DateFormatDayFormatter;
import com.prolificinteractive.materialcalendarview.format.DayFormatter;
import com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter;
import com.prolificinteractive.materialcalendarview.format.TitleFormatter;
import com.prolificinteractive.materialcalendarview.format.WeekDayFormatter;
+
+import org.threeten.bp.DayOfWeek;
+import org.threeten.bp.LocalDate;
+import org.threeten.bp.temporal.WeekFields;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -40,9 +48,6 @@
import java.util.Collection;
import java.util.List;
import java.util.Locale;
-import org.threeten.bp.DayOfWeek;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.temporal.WeekFields;
/**
*
@@ -68,1951 +73,1930 @@
*/
public class MaterialCalendarView extends ViewGroup {
- public static final int INVALID_TILE_DIMENSION = -10;
-
- /**
- * {@linkplain IntDef} annotation for selection mode.
- *
- * @see #setSelectionMode(int)
- * @see #getSelectionMode()
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(
- { SELECTION_MODE_NONE, SELECTION_MODE_SINGLE, SELECTION_MODE_MULTIPLE, SELECTION_MODE_RANGE })
- public @interface SelectionMode {
- }
-
- /**
- * Selection mode that disallows all selection.
- * When changing to this mode, current selection will be cleared.
- */
- public static final int SELECTION_MODE_NONE = 0;
-
- /**
- * Selection mode that allows one selected date at one time. This is the default mode.
- * When switching from {@linkplain #SELECTION_MODE_MULTIPLE}, this will select the same date
- * as from {@linkplain #getSelectedDate()}, which should be the last selected date
- */
- public static final int SELECTION_MODE_SINGLE = 1;
-
- /**
- * Selection mode which allows more than one selected date at one time.
- */
- public static final int SELECTION_MODE_MULTIPLE = 2;
-
- /**
- * Selection mode which allows selection of a range between two dates
- */
- public static final int SELECTION_MODE_RANGE = 3;
-
- /**
- * {@linkplain IntDef} annotation for showOtherDates.
- *
- * @see #setShowOtherDates(int)
- * @see #getShowOtherDates()
- */
- @SuppressLint("UniqueConstants")
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = {
- SHOW_NONE, SHOW_ALL, SHOW_DEFAULTS,
- SHOW_OUT_OF_RANGE, SHOW_OTHER_MONTHS, SHOW_DECORATED_DISABLED
- })
- public @interface ShowOtherDates {
- }
-
- /**
- * Do not show any non-enabled dates
- */
- public static final int SHOW_NONE = 0;
-
- /**
- * Show dates from the proceeding and successive months, in a disabled state.
- * This flag also enables the {@link #SHOW_OUT_OF_RANGE} flag to prevent odd blank areas.
- */
- public static final int SHOW_OTHER_MONTHS = 1;
-
- /**
- * Show dates that are outside of the min-max range.
- * This will only show days from the current month unless {@link #SHOW_OTHER_MONTHS} is enabled.
- */
- public static final int SHOW_OUT_OF_RANGE = 1 << 1;
-
- /**
- * Show days that are individually disabled with decorators.
- * This will only show dates in the current month and inside the minimum and maximum date range.
- */
- public static final int SHOW_DECORATED_DISABLED = 1 << 2;
-
- /**
- * The default flags for showing non-enabled dates. Currently only shows {@link
- * #SHOW_DECORATED_DISABLED}
- */
- public static final int SHOW_DEFAULTS = SHOW_DECORATED_DISABLED;
-
- /**
- * Show all the days
- */
- public static final int SHOW_ALL =
- SHOW_OTHER_MONTHS | SHOW_OUT_OF_RANGE | SHOW_DECORATED_DISABLED;
-
- /**
- * Use this orientation to animate the title vertically
- */
- public static final int VERTICAL = 0;
-
- /**
- * Use this orientation to animate the title horizontally
- */
- public static final int HORIZONTAL = 1;
-
- /**
- * Default tile size in DIPs. This is used in cases where there is no tile size specificed and the
- * view is set to {@linkplain ViewGroup.LayoutParams#WRAP_CONTENT WRAP_CONTENT}
- */
- public static final int DEFAULT_TILE_SIZE_DP = 44;
- private static final int DEFAULT_DAYS_IN_WEEK = 7;
- private static final int DEFAULT_MAX_WEEKS = 6;
- private static final int DAY_NAMES_ROW = 1;
-
- private final TitleChanger titleChanger;
-
- private final TextView title;
- private final ImageView buttonPast;
- private final ImageView buttonFuture;
- private final CalendarPager pager;
- private CalendarPagerAdapter> adapter;
- private CalendarDay currentMonth;
- private LinearLayout topbar;
- private CalendarMode calendarMode;
- /**
- * Used for the dynamic calendar height.
- */
- private boolean mDynamicHeightEnabled;
-
- private final ArrayList dayViewDecorators = new ArrayList<>();
-
- private final OnClickListener onClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (v == buttonFuture) {
- pager.setCurrentItem(pager.getCurrentItem() + 1, true);
- } else if (v == buttonPast) {
- pager.setCurrentItem(pager.getCurrentItem() - 1, true);
- }
+ public static final int INVALID_TILE_DIMENSION = -10;
+ /**
+ * Selection mode that disallows all selection.
+ * When changing to this mode, current selection will be cleared.
+ */
+ public static final int SELECTION_MODE_NONE = 0;
+ /**
+ * Selection mode that allows one selected date at one time. This is the default mode.
+ * When switching from {@linkplain #SELECTION_MODE_MULTIPLE}, this will select the same date
+ * as from {@linkplain #getSelectedDate()}, which should be the last selected date
+ */
+ public static final int SELECTION_MODE_SINGLE = 1;
+ /**
+ * Selection mode which allows more than one selected date at one time.
+ */
+ public static final int SELECTION_MODE_MULTIPLE = 2;
+ /**
+ * Selection mode which allows selection of a range between two dates
+ */
+ public static final int SELECTION_MODE_RANGE = 3;
+ /**
+ * Do not show any non-enabled dates
+ */
+ public static final int SHOW_NONE = 0;
+ /**
+ * Show dates from the proceeding and successive months, in a disabled state.
+ * This flag also enables the {@link #SHOW_OUT_OF_RANGE} flag to prevent odd blank areas.
+ */
+ public static final int SHOW_OTHER_MONTHS = 1;
+ /**
+ * Show dates that are outside of the min-max range.
+ * This will only show days from the current month unless {@link #SHOW_OTHER_MONTHS} is enabled.
+ */
+ public static final int SHOW_OUT_OF_RANGE = 1 << 1;
+ /**
+ * Show days that are individually disabled with decorators.
+ * This will only show dates in the current month and inside the minimum and maximum date range.
+ */
+ public static final int SHOW_DECORATED_DISABLED = 1 << 2;
+ /**
+ * The default flags for showing non-enabled dates. Currently only shows {@link
+ * #SHOW_DECORATED_DISABLED}
+ */
+ public static final int SHOW_DEFAULTS = SHOW_DECORATED_DISABLED;
+ /**
+ * Show all the days
+ */
+ public static final int SHOW_ALL =
+ SHOW_OTHER_MONTHS | SHOW_OUT_OF_RANGE | SHOW_DECORATED_DISABLED;
+ /**
+ * Use this orientation to animate the title vertically
+ */
+ public static final int VERTICAL = 0;
+ /**
+ * Use this orientation to animate the title horizontally
+ */
+ public static final int HORIZONTAL = 1;
+ /**
+ * Default tile size in DIPs. This is used in cases where there is no tile size specificed and the
+ * view is set to {@linkplain ViewGroup.LayoutParams#WRAP_CONTENT WRAP_CONTENT}
+ */
+ public static final int DEFAULT_TILE_SIZE_DP = 44;
+ private static final int DEFAULT_DAYS_IN_WEEK = 7;
+ private static final int DEFAULT_MAX_WEEKS = 6;
+ private static final int DAY_NAMES_ROW = 1;
+ private final TitleChanger titleChanger;
+ private final TextView title;
+ private final ImageView backArrowButton;
+ private final ImageView ForwardArrowButton;
+ private final CalendarPager pager;
+ private final ArrayList dayViewDecorators = new ArrayList<>();
+ private final OnClickListener onClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (v == ForwardArrowButton) {
+ pager.setCurrentItem(pager.getCurrentItem() + 1, true);
+ } else if (v == backArrowButton) {
+ pager.setCurrentItem(pager.getCurrentItem() - 1, true);
+ }
+ }
+ };
+ CharSequence calendarContentDescription;
+ private CalendarPagerAdapter> adapter;
+ private CalendarDay currentMonth;
+ private LinearLayout topbar;
+ private CalendarMode calendarMode;
+ /**
+ * Used for the dynamic calendar height.
+ */
+ private boolean mDynamicHeightEnabled;
+ private CalendarDay minDate = null;
+ private CalendarDay maxDate = null;
+ private OnDateSelectedListener listener;
+ private OnDateLongClickListener longClickListener;
+ private OnMonthChangedListener monthListener;
+ private OnRangeSelectedListener rangeListener;
+ private int accentColor = 0;
+ private int tileHeight = INVALID_TILE_DIMENSION;
+ private int tileWidth = INVALID_TILE_DIMENSION;
+ @SelectionMode
+ private int selectionMode = SELECTION_MODE_SINGLE;
+ private boolean allowClickDaysOutsideCurrentMonth = true;
+ private DayOfWeek firstDayOfWeek;
+ private boolean showWeekDays;
+ private State state;
+
+ public MaterialCalendarView(Context context) {
+ this(context, null);
}
- };
- private final ViewPager.OnPageChangeListener pageChangeListener =
- new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageSelected(int position) {
- titleChanger.setPreviousMonth(currentMonth);
- currentMonth = adapter.getItem(position);
- updateUi();
+ public MaterialCalendarView(Context context, AttributeSet attrs) {
+ super(context, attrs);
- dispatchOnMonthChanged(currentMonth);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ //If we're on good Android versions, turn off clipping for cool effects
+ setClipToPadding(false);
+ setClipChildren(false);
+ } else {
+ //Old Android does not like _not_ clipping view pagers, we need to clip
+ setClipChildren(true);
+ setClipToPadding(true);
}
- @Override
- public void onPageScrollStateChanged(int state) {
+ final LayoutInflater inflater =
+ (LayoutInflater) getContext().getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+ final View content = inflater.inflate(R.layout.calendar_view, null, false);
+
+ topbar = content.findViewById(R.id.header);
+ backArrowButton = content.findViewById(R.id.previous);
+ title = content.findViewById(R.id.month_name);
+ ForwardArrowButton = content.findViewById(R.id.next);
+ pager = new CalendarPager(getContext());
+
+ backArrowButton.setOnClickListener(onClickListener);
+ ForwardArrowButton.setOnClickListener(onClickListener);
+
+ titleChanger = new TitleChanger(title);
+ setOnChangeViewPagerListener();
+ pager.setPageTransformer(false, new ViewPager.PageTransformer() {
+ @Override
+ public void transformPage(View page, float position) {
+ position = (float) Math.sqrt(1 - Math.abs(position));
+ page.setAlpha(position);
+ }
+ });
+
+ TypedArray a = context.getTheme()
+ .obtainStyledAttributes(attrs, R.styleable.MaterialCalendarView, 0, 0);
+ try {
+ int calendarModeIndex = a.getInteger(
+ R.styleable.MaterialCalendarView_mcv_calendarMode,
+ 0
+ );
+ int firstDayOfWeekInt = a.getInteger(
+ R.styleable.MaterialCalendarView_mcv_firstDayOfWeek,
+ -1
+ );
+
+ titleChanger.setOrientation(
+ a.getInteger(
+ R.styleable.MaterialCalendarView_mcv_titleAnimationOrientation,
+ VERTICAL
+ ));
+
+ if (firstDayOfWeekInt >= 1 && firstDayOfWeekInt <= 7) {
+ firstDayOfWeek = DayOfWeek.of(firstDayOfWeekInt);
+ } else {
+ firstDayOfWeek = WeekFields.of(Locale.getDefault()).getFirstDayOfWeek();
+ }
+
+ showWeekDays = a.getBoolean(R.styleable.MaterialCalendarView_mcv_showWeekDays, true);
+
+ newState()
+ .setFirstDayOfWeek(firstDayOfWeek)
+ .setCalendarDisplayMode(CalendarMode.values()[calendarModeIndex])
+ .setShowWeekDays(showWeekDays)
+ .commit();
+
+ setSelectionMode(a.getInteger(
+ R.styleable.MaterialCalendarView_mcv_selectionMode,
+ SELECTION_MODE_SINGLE
+ ));
+
+ final int tileSize = a.getLayoutDimension(
+ R.styleable.MaterialCalendarView_mcv_tileSize,
+ INVALID_TILE_DIMENSION
+ );
+ if (tileSize > INVALID_TILE_DIMENSION) {
+ setTileSize(tileSize);
+ }
+
+ final int tileWidth = a.getLayoutDimension(
+ R.styleable.MaterialCalendarView_mcv_tileWidth,
+ INVALID_TILE_DIMENSION
+ );
+ if (tileWidth > INVALID_TILE_DIMENSION) {
+ setTileWidth(tileWidth);
+ }
+
+ final int tileHeight = a.getLayoutDimension(
+ R.styleable.MaterialCalendarView_mcv_tileHeight,
+ INVALID_TILE_DIMENSION
+ );
+ if (tileHeight > INVALID_TILE_DIMENSION) {
+ setTileHeight(tileHeight);
+ }
+
+ setLeftArrow(
+ a.getResourceId(
+ R.styleable.MaterialCalendarView_mcv_leftArrow,
+ R.drawable.mcv_action_previous
+ )
+ );
+ setRightArrow(
+ a.getResourceId(
+ R.styleable.MaterialCalendarView_mcv_rightArrow,
+ R.drawable.mcv_action_next
+ )
+ );
+
+ setSelectionColor(
+ a.getColor(
+ R.styleable.MaterialCalendarView_mcv_selectionColor,
+ getThemeAccentColor(context)
+ )
+ );
+
+ CharSequence[] array = a.getTextArray(R.styleable.MaterialCalendarView_mcv_weekDayLabels);
+ if (array != null) {
+ setWeekDayFormatter(new ArrayWeekDayFormatter(array));
+ }
+
+ array = a.getTextArray(R.styleable.MaterialCalendarView_mcv_monthLabels);
+ if (array != null) {
+ setTitleFormatter(new MonthArrayTitleFormatter(array));
+ }
+
+ setHeaderTextAppearance(a.getResourceId(
+ R.styleable.MaterialCalendarView_mcv_headerTextAppearance,
+ R.style.TextAppearance_MaterialCalendarWidget_Header
+ ));
+ setWeekDayTextAppearance(a.getResourceId(
+ R.styleable.MaterialCalendarView_mcv_weekDayTextAppearance,
+ R.style.TextAppearance_MaterialCalendarWidget_WeekDay
+ ));
+ setDateTextAppearance(a.getResourceId(
+ R.styleable.MaterialCalendarView_mcv_dateTextAppearance,
+ R.style.TextAppearance_MaterialCalendarWidget_Date
+ ));
+ //noinspection ResourceType
+ setShowOtherDates(a.getInteger(
+ R.styleable.MaterialCalendarView_mcv_showOtherDates,
+ SHOW_DEFAULTS
+ ));
+
+ setAllowClickDaysOutsideCurrentMonth(a.getBoolean(
+ R.styleable.MaterialCalendarView_mcv_allowClickDaysOutsideCurrentMonth,
+ true
+ ));
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ a.recycle();
}
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ // Adapter is created while parsing the TypedArray attrs, so setup has to happen after
+ setupChildren();
+
+ currentMonth = CalendarDay.today();
+ setCurrentDate(currentMonth);
+
+ if (isInEditMode()) {
+ removeView(pager);
+ MonthView monthView = new MonthView(this, currentMonth, getFirstDayOfWeek(), true);
+ monthView.setSelectionColor(getSelectionColor());
+ monthView.setDateTextAppearance(adapter.getDateTextAppearance());
+ monthView.setWeekDayTextAppearance(adapter.getWeekDayTextAppearance());
+ monthView.setShowOtherDates(getShowOtherDates());
+ addView(monthView, new LayoutParams(calendarMode.visibleWeeksCount + DAY_NAMES_ROW));
}
- };
-
- private CalendarDay minDate = null;
- private CalendarDay maxDate = null;
-
- private OnDateSelectedListener listener;
- private OnDateLongClickListener longClickListener;
- private OnMonthChangedListener monthListener;
- private OnRangeSelectedListener rangeListener;
-
- CharSequence calendarContentDescription;
- private int accentColor = 0;
- private int tileHeight = INVALID_TILE_DIMENSION;
- private int tileWidth = INVALID_TILE_DIMENSION;
- @SelectionMode
- private int selectionMode = SELECTION_MODE_SINGLE;
- private boolean allowClickDaysOutsideCurrentMonth = true;
- private DayOfWeek firstDayOfWeek;
- private boolean showWeekDays;
-
- private State state;
-
- public MaterialCalendarView(Context context) {
- this(context, null);
- }
-
- public MaterialCalendarView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- //If we're on good Android versions, turn off clipping for cool effects
- setClipToPadding(false);
- setClipChildren(false);
- } else {
- //Old Android does not like _not_ clipping view pagers, we need to clip
- setClipChildren(true);
- setClipToPadding(true);
- }
-
- final LayoutInflater inflater =
- (LayoutInflater) getContext().getSystemService(Service.LAYOUT_INFLATER_SERVICE);
- final View content = inflater.inflate(R.layout.calendar_view, null, false);
-
- topbar = content.findViewById(R.id.header);
- buttonPast = content.findViewById(R.id.previous);
- title = content.findViewById(R.id.month_name);
- buttonFuture = content.findViewById(R.id.next);
- pager = new CalendarPager(getContext());
-
- buttonPast.setOnClickListener(onClickListener);
- buttonFuture.setOnClickListener(onClickListener);
-
- titleChanger = new TitleChanger(title);
-
- pager.setOnPageChangeListener(pageChangeListener);
- pager.setPageTransformer(false, new ViewPager.PageTransformer() {
- @Override
- public void transformPage(View page, float position) {
- position = (float) Math.sqrt(1 - Math.abs(position));
- page.setAlpha(position);
- }
- });
-
- TypedArray a = context.getTheme()
- .obtainStyledAttributes(attrs, R.styleable.MaterialCalendarView, 0, 0);
- try {
- int calendarModeIndex = a.getInteger(
- R.styleable.MaterialCalendarView_mcv_calendarMode,
- 0
- );
- int firstDayOfWeekInt = a.getInteger(
- R.styleable.MaterialCalendarView_mcv_firstDayOfWeek,
- -1
- );
-
- titleChanger.setOrientation(
- a.getInteger(
- R.styleable.MaterialCalendarView_mcv_titleAnimationOrientation,
- VERTICAL
- ));
-
- if (firstDayOfWeekInt >= 1 && firstDayOfWeekInt <= 7) {
- firstDayOfWeek = DayOfWeek.of(firstDayOfWeekInt);
- } else {
- firstDayOfWeek = WeekFields.of(Locale.getDefault()).getFirstDayOfWeek();
- }
-
- showWeekDays = a.getBoolean(R.styleable.MaterialCalendarView_mcv_showWeekDays, true);
-
- newState()
- .setFirstDayOfWeek(firstDayOfWeek)
- .setCalendarDisplayMode(CalendarMode.values()[calendarModeIndex])
- .setShowWeekDays(showWeekDays)
- .commit();
-
- setSelectionMode(a.getInteger(
- R.styleable.MaterialCalendarView_mcv_selectionMode,
- SELECTION_MODE_SINGLE
- ));
-
- final int tileSize = a.getLayoutDimension(
- R.styleable.MaterialCalendarView_mcv_tileSize,
- INVALID_TILE_DIMENSION
- );
- if (tileSize > INVALID_TILE_DIMENSION) {
- setTileSize(tileSize);
- }
-
- final int tileWidth = a.getLayoutDimension(
- R.styleable.MaterialCalendarView_mcv_tileWidth,
- INVALID_TILE_DIMENSION
- );
- if (tileWidth > INVALID_TILE_DIMENSION) {
- setTileWidth(tileWidth);
- }
-
- final int tileHeight = a.getLayoutDimension(
- R.styleable.MaterialCalendarView_mcv_tileHeight,
- INVALID_TILE_DIMENSION
- );
- if (tileHeight > INVALID_TILE_DIMENSION) {
- setTileHeight(tileHeight);
- }
-
- setLeftArrow(
- a.getResourceId(
- R.styleable.MaterialCalendarView_mcv_leftArrow,
- R.drawable.mcv_action_previous
- )
- );
- setRightArrow(
- a.getResourceId(
- R.styleable.MaterialCalendarView_mcv_rightArrow,
- R.drawable.mcv_action_next
- )
- );
-
- setSelectionColor(
- a.getColor(
- R.styleable.MaterialCalendarView_mcv_selectionColor,
- getThemeAccentColor(context)
- )
- );
-
- CharSequence[] array = a.getTextArray(R.styleable.MaterialCalendarView_mcv_weekDayLabels);
- if (array != null) {
- setWeekDayFormatter(new ArrayWeekDayFormatter(array));
- }
-
- array = a.getTextArray(R.styleable.MaterialCalendarView_mcv_monthLabels);
- if (array != null) {
- setTitleFormatter(new MonthArrayTitleFormatter(array));
- }
-
- setHeaderTextAppearance(a.getResourceId(
- R.styleable.MaterialCalendarView_mcv_headerTextAppearance,
- R.style.TextAppearance_MaterialCalendarWidget_Header
- ));
- setWeekDayTextAppearance(a.getResourceId(
- R.styleable.MaterialCalendarView_mcv_weekDayTextAppearance,
- R.style.TextAppearance_MaterialCalendarWidget_WeekDay
- ));
- setDateTextAppearance(a.getResourceId(
- R.styleable.MaterialCalendarView_mcv_dateTextAppearance,
- R.style.TextAppearance_MaterialCalendarWidget_Date
- ));
- //noinspection ResourceType
- setShowOtherDates(a.getInteger(
- R.styleable.MaterialCalendarView_mcv_showOtherDates,
- SHOW_DEFAULTS
- ));
-
- setAllowClickDaysOutsideCurrentMonth(a.getBoolean(
- R.styleable.MaterialCalendarView_mcv_allowClickDaysOutsideCurrentMonth,
- true
- ));
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- a.recycle();
- }
-
- // Adapter is created while parsing the TypedArray attrs, so setup has to happen after
- setupChildren();
-
- currentMonth = CalendarDay.today();
- setCurrentDate(currentMonth);
-
- if (isInEditMode()) {
- removeView(pager);
- MonthView monthView = new MonthView(this, currentMonth, getFirstDayOfWeek(), true);
- monthView.setSelectionColor(getSelectionColor());
- monthView.setDateTextAppearance(adapter.getDateTextAppearance());
- monthView.setWeekDayTextAppearance(adapter.getWeekDayTextAppearance());
- monthView.setShowOtherDates(getShowOtherDates());
- addView(monthView, new LayoutParams(calendarMode.visibleWeeksCount + DAY_NAMES_ROW));
- }
- }
-
- private void setupChildren() {
- addView(topbar);
-
- pager.setId(R.id.mcv_pager);
- pager.setOffscreenPageLimit(1);
- int tileHeight = showWeekDays ? calendarMode.visibleWeeksCount + DAY_NAMES_ROW
- : calendarMode.visibleWeeksCount;
- addView(pager, new LayoutParams(tileHeight));
- }
-
- private void updateUi() {
- titleChanger.change(currentMonth);
- enableView(buttonPast, canGoBack());
- enableView(buttonFuture, canGoForward());
- }
-
- /**
- * Change the selection mode of the calendar. The default mode is {@linkplain
- * #SELECTION_MODE_SINGLE}
- *
- * @param mode the selection mode to change to. This must be one of
- * {@linkplain #SELECTION_MODE_NONE}, {@linkplain #SELECTION_MODE_SINGLE},
- * {@linkplain #SELECTION_MODE_RANGE} or {@linkplain #SELECTION_MODE_MULTIPLE}.
- * Unknown values will act as {@linkplain #SELECTION_MODE_SINGLE}
- * @see #getSelectionMode()
- * @see #SELECTION_MODE_NONE
- * @see #SELECTION_MODE_SINGLE
- * @see #SELECTION_MODE_MULTIPLE
- * @see #SELECTION_MODE_RANGE
- */
- public void setSelectionMode(final @SelectionMode int mode) {
- final @SelectionMode int oldMode = this.selectionMode;
- this.selectionMode = mode;
- switch (mode) {
- case SELECTION_MODE_RANGE:
- clearSelection();
- break;
- case SELECTION_MODE_MULTIPLE:
- break;
- case SELECTION_MODE_SINGLE:
- if (oldMode == SELECTION_MODE_MULTIPLE || oldMode == SELECTION_MODE_RANGE) {
- //We should only have one selection now, so we should pick one
- List dates = getSelectedDates();
- if (!dates.isEmpty()) {
- setSelectedDate(getSelectedDate());
- }
+ }
+
+ private static int getThemeAccentColor(Context context) {
+ int colorAttr;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ colorAttr = android.R.attr.colorAccent;
+ } else {
+ //Get colorAccent defined for AppCompat
+ colorAttr =
+ context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
+ }
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(colorAttr, outValue, true);
+ return outValue.data;
+ }
+
+ /**
+ * @param showOtherDates int flag for show other dates
+ * @return true if the other months flag is set
+ */
+ public static boolean showOtherMonths(@ShowOtherDates int showOtherDates) {
+ return (showOtherDates & SHOW_OTHER_MONTHS) != 0;
+ }
+
+ /**
+ * @param showOtherDates int flag for show other dates
+ * @return true if the out of range flag is set
+ */
+ public static boolean showOutOfRange(@ShowOtherDates int showOtherDates) {
+ return (showOtherDates & SHOW_OUT_OF_RANGE) != 0;
+ }
+
+ /**
+ * @param showOtherDates int flag for show other dates
+ * @return true if the decorated disabled flag is set
+ */
+ public static boolean showDecoratedDisabled(@ShowOtherDates int showOtherDates) {
+ return (showOtherDates & SHOW_DECORATED_DISABLED) != 0;
+ }
+
+ /**
+ * Clamp the size to the measure spec.
+ *
+ * @param size Size we want to be
+ * @param spec Measure spec to clamp against
+ * @return the appropriate size to pass to {@linkplain View#setMeasuredDimension(int, int)}
+ */
+ private static int clampSize(int size, int spec) {
+ int specMode = MeasureSpec.getMode(spec);
+ int specSize = MeasureSpec.getSize(spec);
+ switch (specMode) {
+ case MeasureSpec.EXACTLY: {
+ return specSize;
+ }
+ case MeasureSpec.AT_MOST: {
+ return Math.min(size, specSize);
+ }
+ case MeasureSpec.UNSPECIFIED:
+ default: {
+ return size;
+ }
+ }
+ }
+
+ /**
+ * Used for enabling or disabling views, while also changing the alpha.
+ *
+ * @param view The view to enable or disable.
+ * @param enable Whether to enable or disable the view.
+ */
+ private static void enableView(final View view, final boolean enable) {
+ view.setEnabled(enable);
+ view.setAlpha(enable ? 1f : 0.1f);
+ }
+
+ private void setOnChangeViewPagerListener() {
+ pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ titleChanger.setPreviousMonth(currentMonth);
+ currentMonth = adapter.getItem(pager.getCurrentItem());
+ updateUi();
+ dispatchOnMonthChanged(currentMonth);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+ });
+ }
+
+ private void setupChildren() {
+ addView(topbar);
+
+ pager.setId(R.id.mcv_pager);
+ pager.setOffscreenPageLimit(1);
+ int tileHeight = showWeekDays ? calendarMode.visibleWeeksCount + DAY_NAMES_ROW
+ : calendarMode.visibleWeeksCount;
+ addView(pager, new LayoutParams(tileHeight));
+ }
+
+ private void updateUi() {
+ titleChanger.change(currentMonth);
+ enableView(backArrowButton, canGoBack());
+ enableView(ForwardArrowButton, canGoForward());
+ }
+
+ /**
+ * Go to previous month or week without using the button {@link #backArrowButton}. Should only go to
+ * previous if {@link #canGoBack()} is true, meaning it's possible to go to the previous month
+ * or week.
+ */
+ public void goToPrevious() {
+ if (canGoBack()) {
+ pager.setCurrentItem(pager.getCurrentItem() - 1, true);
+ }
+ }
+
+ /**
+ * Go to next month or week without using the button {@link #ForwardArrowButton}. Should only go to
+ * next if {@link #canGoForward()} is enabled, meaning it's possible to go to the next month or
+ * week.
+ */
+ public void goToNext() {
+ if (canGoForward()) {
+ pager.setCurrentItem(pager.getCurrentItem() + 1, true);
}
- break;
- default:
- case SELECTION_MODE_NONE:
- this.selectionMode = SELECTION_MODE_NONE;
- if (oldMode != SELECTION_MODE_NONE) {
- //No selection! Clear out!
- clearSelection();
+ }
+
+ /**
+ * Get the current selection mode. The default mode is {@linkplain #SELECTION_MODE_SINGLE}
+ *
+ * @return the current selection mode
+ * @see #setSelectionMode(int)
+ * @see #SELECTION_MODE_NONE
+ * @see #SELECTION_MODE_SINGLE
+ * @see #SELECTION_MODE_MULTIPLE
+ * @see #SELECTION_MODE_RANGE
+ */
+ @SelectionMode
+ public int getSelectionMode() {
+ return selectionMode;
+ }
+
+ /**
+ * Change the selection mode of the calendar. The default mode is {@linkplain
+ * #SELECTION_MODE_SINGLE}
+ *
+ * @param mode the selection mode to change to. This must be one of
+ * {@linkplain #SELECTION_MODE_NONE}, {@linkplain #SELECTION_MODE_SINGLE},
+ * {@linkplain #SELECTION_MODE_RANGE} or {@linkplain #SELECTION_MODE_MULTIPLE}.
+ * Unknown values will act as {@linkplain #SELECTION_MODE_SINGLE}
+ * @see #getSelectionMode()
+ * @see #SELECTION_MODE_NONE
+ * @see #SELECTION_MODE_SINGLE
+ * @see #SELECTION_MODE_MULTIPLE
+ * @see #SELECTION_MODE_RANGE
+ */
+ public void setSelectionMode(final @SelectionMode int mode) {
+ final @SelectionMode int oldMode = this.selectionMode;
+ this.selectionMode = mode;
+ switch (mode) {
+ case SELECTION_MODE_RANGE:
+ clearSelection();
+ break;
+ case SELECTION_MODE_MULTIPLE:
+ break;
+ case SELECTION_MODE_SINGLE:
+ if (oldMode == SELECTION_MODE_MULTIPLE || oldMode == SELECTION_MODE_RANGE) {
+ //We should only have one selection now, so we should pick one
+ List dates = getSelectedDates();
+ if (!dates.isEmpty()) {
+ setSelectedDate(getSelectedDate());
+ }
+ }
+ break;
+ default:
+ case SELECTION_MODE_NONE:
+ this.selectionMode = SELECTION_MODE_NONE;
+ if (oldMode != SELECTION_MODE_NONE) {
+ //No selection! Clear out!
+ clearSelection();
+ }
+ break;
}
- break;
- }
-
- adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE);
- }
-
- /**
- * Go to previous month or week without using the button {@link #buttonPast}. Should only go to
- * previous if {@link #canGoBack()} is true, meaning it's possible to go to the previous month
- * or week.
- */
- public void goToPrevious() {
- if (canGoBack()) {
- pager.setCurrentItem(pager.getCurrentItem() - 1, true);
- }
- }
-
- /**
- * Go to next month or week without using the button {@link #buttonFuture}. Should only go to
- * next if {@link #canGoForward()} is enabled, meaning it's possible to go to the next month or
- * week.
- */
- public void goToNext() {
- if (canGoForward()) {
- pager.setCurrentItem(pager.getCurrentItem() + 1, true);
- }
- }
-
- /**
- * Get the current selection mode. The default mode is {@linkplain #SELECTION_MODE_SINGLE}
- *
- * @return the current selection mode
- * @see #setSelectionMode(int)
- * @see #SELECTION_MODE_NONE
- * @see #SELECTION_MODE_SINGLE
- * @see #SELECTION_MODE_MULTIPLE
- * @see #SELECTION_MODE_RANGE
- */
- @SelectionMode
- public int getSelectionMode() {
- return selectionMode;
- }
-
- /**
- * Use {@link #getTileWidth()} or {@link #getTileHeight()} instead. This method is deprecated
- * and will just return the largest of the two sizes.
- *
- * @return tile height or width, whichever is larger
- */
- @Deprecated
- public int getTileSize() {
- return Math.max(tileHeight, tileWidth);
- }
-
- /**
- * Set the size of each tile that makes up the calendar.
- * Each day is 1 tile, so the widget is 7 tiles wide and 7 or 8 tiles tall
- * depending on the visibility of the {@link #topbar}.
- *
- * @param size the new size for each tile in pixels
- */
- public void setTileSize(int size) {
- this.tileWidth = size;
- this.tileHeight = size;
- requestLayout();
- }
-
- /**
- * @param tileSizeDp the new size for each tile in dips
- * @see #setTileSize(int)
- */
- public void setTileSizeDp(int tileSizeDp) {
- setTileSize(dpToPx(tileSizeDp));
- }
-
- /**
- * @return the height of tiles in pixels
- */
- public int getTileHeight() {
- return tileHeight;
- }
-
- /**
- * Set the height of each tile that makes up the calendar.
- *
- * @param height the new height for each tile in pixels
- */
- public void setTileHeight(int height) {
- this.tileHeight = height;
- requestLayout();
- }
-
- /**
- * @param tileHeightDp the new height for each tile in dips
- * @see #setTileHeight(int)
- */
- public void setTileHeightDp(int tileHeightDp) {
- setTileHeight(dpToPx(tileHeightDp));
- }
-
- /**
- * @return the width of tiles in pixels
- */
- public int getTileWidth() {
- return tileWidth;
- }
-
- /**
- * Set the width of each tile that makes up the calendar.
- *
- * @param width the new width for each tile in pixels
- */
- public void setTileWidth(int width) {
- this.tileWidth = width;
- requestLayout();
- }
-
- /**
- * @param tileWidthDp the new width for each tile in dips
- * @see #setTileWidth(int)
- */
- public void setTileWidthDp(int tileWidthDp) {
- setTileWidth(dpToPx(tileWidthDp));
- }
-
- private int dpToPx(int dp) {
- return (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()
- );
- }
-
- /**
- * Whether the pager can page forward, meaning the future month is enabled.
- *
- * @return true if there is a future month that can be shown
- */
- public boolean canGoForward() {
- return pager.getCurrentItem() < (adapter.getCount() - 1);
- }
-
- /**
- * Whether the pager can page backward, meaning the previous month is enabled.
- *
- * @return true if there is a previous month that can be shown
- */
- public boolean canGoBack() {
- return pager.getCurrentItem() > 0;
- }
-
- /**
- * Pass all touch events to the pager so scrolling works on the edges of the calendar view.
- */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return pager.dispatchTouchEvent(event);
- }
-
- /**
- * @return the color used for the selection
- */
- public int getSelectionColor() {
- return accentColor;
- }
-
- /**
- * @param color The selection color
- */
- public void setSelectionColor(int color) {
- if (color == 0) {
- if (!isInEditMode()) {
- return;
- } else {
- color = Color.GRAY;
- }
- }
- accentColor = color;
- adapter.setSelectionColor(color);
- invalidate();
- }
-
- /**
- * Set content description for button past
- *
- * @param description String to use as content description
- */
- public void setContentDescriptionArrowPast(final CharSequence description) {
- buttonPast.setContentDescription(description);
- }
-
- /**
- * Set content description for button future
- *
- * @param description String to use as content description
- */
- public void setContentDescriptionArrowFuture(final CharSequence description) {
- buttonFuture.setContentDescription(description);
- }
-
- /**
- * Set content description for calendar
- *
- * @param description String to use as content description
- */
- public void setContentDescriptionCalendar(final CharSequence description) {
- calendarContentDescription = description;
- }
-
- /**
- * Get content description for calendar
- *
- * @return calendar's content description
- */
- public CharSequence getCalendarContentDescription() {
- return calendarContentDescription != null
- ? calendarContentDescription
- : getContext().getString(R.string.calendar);
- }
-
- /**
- * Set a formatter for day content description.
- *
- * @param formatter the new formatter, null for default
- */
- public void setDayFormatterContentDescription(DayFormatter formatter) {
- adapter.setDayFormatterContentDescription(formatter);
- }
-
- /**
- * @return icon used for the left arrow
- */
- public Drawable getLeftArrow() {
- return buttonPast.getDrawable();
- }
-
- /**
- * @param icon the new icon to use for the left paging arrow
- */
- public void setLeftArrow(@DrawableRes final int icon) {
- buttonPast.setImageResource(icon);
- }
-
- /**
- * @return icon used for the right arrow
- */
- public Drawable getRightArrow() {
- return buttonFuture.getDrawable();
- }
-
- /**
- * @param icon the new icon to use for the right paging arrow
- */
- public void setRightArrow(@DrawableRes final int icon) {
- buttonFuture.setImageResource(icon);
- }
-
- /**
- * @param resourceId The text appearance resource id.
- */
- public void setHeaderTextAppearance(int resourceId) {
- title.setTextAppearance(getContext(), resourceId);
- }
-
- /**
- * @param resourceId The text appearance resource id.
- */
- public void setDateTextAppearance(int resourceId) {
- adapter.setDateTextAppearance(resourceId);
- }
-
- /**
- * @param resourceId The text appearance resource id.
- */
- public void setWeekDayTextAppearance(int resourceId) {
- adapter.setWeekDayTextAppearance(resourceId);
- }
-
- /**
- * Get the currently selected date, or null if no selection. Depending on the selection mode,
- * you might get different results.
- *
- *
For {@link #SELECTION_MODE_SINGLE}, returns the selected date.
- *
For {@link #SELECTION_MODE_MULTIPLE}, returns the last date selected.
- *
For {@link #SELECTION_MODE_RANGE}, returns the last date of the range. In most cases, you
- * should probably be using {@link #getSelectedDates()}.
- *
For {@link #SELECTION_MODE_NONE}, returns null.
- *
- * @return The selected day, or null if no selection. If in multiple selection mode, this
- * will return the last date of the list of selected dates.
- * @see MaterialCalendarView#getSelectedDates()
- */
- @Nullable public CalendarDay getSelectedDate() {
- List dates = adapter.getSelectedDates();
- if (dates.isEmpty()) {
- return null;
- } else {
- return dates.get(dates.size() - 1);
- }
- }
-
- /**
- * Return the list of currently selected dates. Mostly useful for {@link #SELECTION_MODE_MULTIPLE}
- * and {@link #SELECTION_MODE_RANGE}. For the other modes, check {@link #getSelectedDate()}.
- *
- *
For {@link #SELECTION_MODE_MULTIPLE}, returns the list in the order of selection.
- *
For {@link #SELECTION_MODE_RANGE}, returns the range of dates ordered chronologically.
- *
- * @return All of the currently selected dates.
- * @see MaterialCalendarView#getSelectedDate()
- */
- @NonNull public List getSelectedDates() {
- return adapter.getSelectedDates();
- }
-
- /**
- * Clear the currently selected date(s)
- */
- public void clearSelection() {
- List dates = getSelectedDates();
- adapter.clearSelections();
- for (CalendarDay day : dates) {
- dispatchOnDateSelected(day, false);
- }
- }
-
- /**
- * @param date a Date set to a day to select. Null to clear selection
- */
- public void setSelectedDate(@Nullable LocalDate date) {
- setSelectedDate(CalendarDay.from(date));
- }
-
- /**
- * @param date a Date to set as selected. Null to clear selection
- */
- public void setSelectedDate(@Nullable CalendarDay date) {
- clearSelection();
- if (date != null) {
- setDateSelected(date, true);
- }
- }
-
- /**
- * @param day a CalendarDay to change. Passing null does nothing
- * @param selected true if day should be selected, false to deselect
- */
- public void setDateSelected(@Nullable CalendarDay day, boolean selected) {
- if (day == null) {
- return;
- }
- adapter.setDateSelected(day, selected);
- }
-
- /**
- * Get the current first day of the month in month mode, or the first visible day of the
- * currently visible week.
- *
- * For example, in week mode, if the week is July 29th, 2018 to August 4th, 2018,
- * this will return July 29th, 2018. If in month mode and the month is august, then this method
- * will return August 1st, 2018.
- *
- * @return The current month or week shown, will be set to first day of the month in month mode,
- * or the first visible day for a week.
- */
- public CalendarDay getCurrentDate() {
- return adapter.getItem(pager.getCurrentItem());
- }
-
- /**
- * Set the calendar to a specific month or week based on a date.
- *
- * In month mode, the calendar will be set to the corresponding month.
- *
- * In week mode, the calendar will be set to the corresponding week.
- *
- * @param calendar a Calendar set to a day to focus the calendar on. Null will do nothing
- */
- public void setCurrentDate(@Nullable LocalDate calendar) {
- setCurrentDate(CalendarDay.from(calendar));
- }
-
- /**
- * Set the calendar to a specific month or week based on a date.
- *
- * In month mode, the calendar will be set to the corresponding month.
- *
- * In week mode, the calendar will be set to the corresponding week.
- *
- * @param day a CalendarDay to focus the calendar on. Null will do nothing
- */
- public void setCurrentDate(@Nullable CalendarDay day) {
- setCurrentDate(day, true);
- }
-
- /**
- * Set the calendar to a specific month or week based on a date.
- *
- * In month mode, the calendar will be set to the corresponding month.
- *
- * In week mode, the calendar will be set to the corresponding week.
- *
- * @param day a CalendarDay to focus the calendar on. Null will do nothing
- * @param useSmoothScroll use smooth scroll when changing months.
- */
- public void setCurrentDate(@Nullable CalendarDay day, boolean useSmoothScroll) {
- if (day == null) {
- return;
- }
- int index = adapter.getIndexForDay(day);
- pager.setCurrentItem(index, useSmoothScroll);
- updateUi();
- }
-
- /**
- * @return the minimum selectable date for the calendar, if any
- */
- public CalendarDay getMinimumDate() {
- return minDate;
- }
-
- /**
- * @return the maximum selectable date for the calendar, if any
- */
- public CalendarDay getMaximumDate() {
- return maxDate;
- }
-
- /**
- * The default value is {@link #SHOW_DEFAULTS}, which currently is just {@link
- * #SHOW_DECORATED_DISABLED}.
- * This means that the default visible days are of the current month, in the min-max range.
- *
- * @param showOtherDates flags for showing non-enabled dates
- * @see #SHOW_ALL
- * @see #SHOW_NONE
- * @see #SHOW_DEFAULTS
- * @see #SHOW_OTHER_MONTHS
- * @see #SHOW_OUT_OF_RANGE
- * @see #SHOW_DECORATED_DISABLED
- */
- public void setShowOtherDates(@ShowOtherDates int showOtherDates) {
- adapter.setShowOtherDates(showOtherDates);
- }
-
- /**
- * Allow the user to click on dates from other months that are not out of range. Go to next or
- * previous month if a day outside the current month is clicked. The day still need to be
- * enabled to be selected.
- * Default value is true. Should be used with {@link #SHOW_OTHER_MONTHS}.
- *
- * @param enabled True to allow the user to click on a day outside current month displayed
- */
- public void setAllowClickDaysOutsideCurrentMonth(final boolean enabled) {
- this.allowClickDaysOutsideCurrentMonth = enabled;
- }
-
- /**
- * Set a formatter for weekday labels.
- *
- * @param formatter the new formatter, null for default
- */
- public void setWeekDayFormatter(WeekDayFormatter formatter) {
- adapter.setWeekDayFormatter(formatter == null ? WeekDayFormatter.DEFAULT : formatter);
- }
-
- /**
- * Set a formatter for day labels.
- *
- * @param formatter the new formatter, null for default
- */
- public void setDayFormatter(DayFormatter formatter) {
- adapter.setDayFormatter(formatter == null ? DayFormatter.DEFAULT : formatter);
- }
-
- /**
- * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.WeekDayFormatter}
- * with the provided week day labels
- *
- * @param weekDayLabels Labels to use for the days of the week
- * @see com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter
- * @see #setWeekDayFormatter(com.prolificinteractive.materialcalendarview.format.WeekDayFormatter)
- */
- public void setWeekDayLabels(CharSequence[] weekDayLabels) {
- setWeekDayFormatter(new ArrayWeekDayFormatter(weekDayLabels));
- }
-
- /**
- * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.WeekDayFormatter}
- * with the provided week day labels
- *
- * @param arrayRes String array resource of week day labels
- * @see com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter
- * @see #setWeekDayFormatter(com.prolificinteractive.materialcalendarview.format.WeekDayFormatter)
- */
- public void setWeekDayLabels(@ArrayRes int arrayRes) {
- setWeekDayLabels(getResources().getTextArray(arrayRes));
- }
-
- /**
- * @return int of flags used for showing non-enabled dates
- * @see #SHOW_ALL
- * @see #SHOW_NONE
- * @see #SHOW_DEFAULTS
- * @see #SHOW_OTHER_MONTHS
- * @see #SHOW_OUT_OF_RANGE
- * @see #SHOW_DECORATED_DISABLED
- */
- @ShowOtherDates
- public int getShowOtherDates() {
- return adapter.getShowOtherDates();
- }
-
- /**
- * @return true if allow click on days outside current month displayed
- */
- public boolean allowClickDaysOutsideCurrentMonth() {
- return allowClickDaysOutsideCurrentMonth;
- }
-
- /**
- * @return true if the week days names are shown
- */
- public boolean isShowWeekDays() {
- return showWeekDays;
- }
-
- /**
- * Set a custom formatter for the month/year title
- *
- * @param titleFormatter new formatter to use, null to use default formatter
- */
- public void setTitleFormatter(@Nullable TitleFormatter titleFormatter) {
- titleChanger.setTitleFormatter(titleFormatter);
- adapter.setTitleFormatter(titleFormatter);
- updateUi();
- }
-
- /**
- * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.TitleFormatter}
- * using the provided month labels
- *
- * @param monthLabels month labels to use
- * @see com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter
- * @see #setTitleFormatter(com.prolificinteractive.materialcalendarview.format.TitleFormatter)
- */
- public void setTitleMonths(CharSequence[] monthLabels) {
- setTitleFormatter(new MonthArrayTitleFormatter(monthLabels));
- }
-
- /**
- * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.TitleFormatter}
- * using the provided month labels
- *
- * @param arrayRes String array resource of month labels to use
- * @see com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter
- * @see #setTitleFormatter(com.prolificinteractive.materialcalendarview.format.TitleFormatter)
- */
- public void setTitleMonths(@ArrayRes int arrayRes) {
- setTitleMonths(getResources().getTextArray(arrayRes));
- }
-
- /**
- * Change the title animation orientation to have a different look and feel.
- *
- * @param orientation {@link MaterialCalendarView#VERTICAL} or {@link
- * MaterialCalendarView#HORIZONTAL}
- */
- public void setTitleAnimationOrientation(final int orientation) {
- titleChanger.setOrientation(orientation);
- }
-
- /**
- * Get the orientation of the animation of the title.
- *
- * @return Title animation orientation {@link MaterialCalendarView#VERTICAL} or {@link
- * MaterialCalendarView#HORIZONTAL}
- */
- public int getTitleAnimationOrientation() {
- return titleChanger.getOrientation();
- }
-
- /**
- * Sets the visibility {@link #topbar}, which contains
- * the previous month button {@link #buttonPast}, next month button {@link #buttonFuture},
- * and the month title {@link #title}.
- *
- * @param visible Boolean indicating if the topbar is visible
- */
- public void setTopbarVisible(boolean visible) {
- topbar.setVisibility(visible ? View.VISIBLE : View.GONE);
- requestLayout();
- }
-
- /**
- * @return true if the topbar is visible
- */
- public boolean getTopbarVisible() {
- return topbar.getVisibility() == View.VISIBLE;
- }
-
- /**
- * Get the current {@link CalendarMode} set of the Calendar.
- *
- * @return Whichever mode the calendar is currently in.
- */
- public CalendarMode getCalendarMode() {
- return calendarMode;
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- SavedState ss = new SavedState(super.onSaveInstanceState());
- ss.showOtherDates = getShowOtherDates();
- ss.allowClickDaysOutsideCurrentMonth = allowClickDaysOutsideCurrentMonth();
- ss.minDate = getMinimumDate();
- ss.maxDate = getMaximumDate();
- ss.selectedDates = getSelectedDates();
- ss.selectionMode = getSelectionMode();
- ss.topbarVisible = getTopbarVisible();
- ss.dynamicHeightEnabled = mDynamicHeightEnabled;
- ss.currentMonth = currentMonth;
- ss.cacheCurrentPosition = state.cacheCurrentPosition;
- return ss;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
- state().edit()
- .setMinimumDate(ss.minDate)
- .setMaximumDate(ss.maxDate)
- .isCacheCalendarPositionEnabled(ss.cacheCurrentPosition)
- .commit();
-
- setShowOtherDates(ss.showOtherDates);
- setAllowClickDaysOutsideCurrentMonth(ss.allowClickDaysOutsideCurrentMonth);
- clearSelection();
- for (CalendarDay calendarDay : ss.selectedDates) {
- setDateSelected(calendarDay, true);
- }
- setTopbarVisible(ss.topbarVisible);
- setSelectionMode(ss.selectionMode);
- setDynamicHeightEnabled(ss.dynamicHeightEnabled);
- setCurrentDate(ss.currentMonth);
- }
-
- @Override
- protected void dispatchSaveInstanceState(@NonNull SparseArray container) {
- dispatchFreezeSelfOnly(container);
- }
-
- @Override
- protected void dispatchRestoreInstanceState(@NonNull SparseArray container) {
- dispatchThawSelfOnly(container);
- }
-
- private void setRangeDates(CalendarDay min, CalendarDay max) {
- CalendarDay c = currentMonth;
- adapter.setRangeDates(min, max);
- currentMonth = c;
- if (min != null) {
- currentMonth = min.isAfter(currentMonth) ? min : currentMonth;
- }
- int position = adapter.getIndexForDay(c);
- pager.setCurrentItem(position, false);
- updateUi();
- }
-
- public static class SavedState extends BaseSavedState {
-
- int showOtherDates = SHOW_DEFAULTS;
- boolean allowClickDaysOutsideCurrentMonth = true;
- CalendarDay minDate = null;
- CalendarDay maxDate = null;
- List selectedDates = new ArrayList<>();
- boolean topbarVisible = true;
- int selectionMode = SELECTION_MODE_SINGLE;
- boolean dynamicHeightEnabled = false;
- CalendarDay currentMonth = null;
- boolean cacheCurrentPosition;
-
- SavedState(Parcelable superState) {
- super(superState);
+
+ adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE);
+ }
+
+ /**
+ * Use {@link #getTileWidth()} or {@link #getTileHeight()} instead. This method is deprecated
+ * and will just return the largest of the two sizes.
+ *
+ * @return tile height or width, whichever is larger
+ */
+ @Deprecated
+ public int getTileSize() {
+ return Math.max(tileHeight, tileWidth);
+ }
+
+ /**
+ * Set the size of each tile that makes up the calendar.
+ * Each day is 1 tile, so the widget is 7 tiles wide and 7 or 8 tiles tall
+ * depending on the visibility of the {@link #topbar}.
+ *
+ * @param size the new size for each tile in pixels
+ */
+ public void setTileSize(int size) {
+ this.tileWidth = size;
+ this.tileHeight = size;
+ requestLayout();
+ }
+
+ /**
+ * @param tileSizeDp the new size for each tile in dips
+ * @see #setTileSize(int)
+ */
+ public void setTileSizeDp(int tileSizeDp) {
+ setTileSize(dpToPx(tileSizeDp));
+ }
+
+ /**
+ * @return the height of tiles in pixels
+ */
+ public int getTileHeight() {
+ return tileHeight;
+ }
+
+ /**
+ * Set the height of each tile that makes up the calendar.
+ *
+ * @param height the new height for each tile in pixels
+ */
+ public void setTileHeight(int height) {
+ this.tileHeight = height;
+ requestLayout();
+ }
+
+ /**
+ * @param tileHeightDp the new height for each tile in dips
+ * @see #setTileHeight(int)
+ */
+ public void setTileHeightDp(int tileHeightDp) {
+ setTileHeight(dpToPx(tileHeightDp));
+ }
+
+ /**
+ * @return the width of tiles in pixels
+ */
+ public int getTileWidth() {
+ return tileWidth;
+ }
+
+ /**
+ * Set the width of each tile that makes up the calendar.
+ *
+ * @param width the new width for each tile in pixels
+ */
+ public void setTileWidth(int width) {
+ this.tileWidth = width;
+ requestLayout();
+ }
+
+ /**
+ * @param tileWidthDp the new width for each tile in dips
+ * @see #setTileWidth(int)
+ */
+ public void setTileWidthDp(int tileWidthDp) {
+ setTileWidth(dpToPx(tileWidthDp));
+ }
+
+ private int dpToPx(int dp) {
+ return (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()
+ );
+ }
+
+ /**
+ * Whether the pager can page forward, meaning the future month is enabled.
+ *
+ * @return true if there is a future month that can be shown
+ */
+ public boolean canGoForward() {
+ return pager.getCurrentItem() < (adapter.getCount() - 1);
+ }
+
+ /**
+ * Whether the pager can page backward, meaning the previous month is enabled.
+ *
+ * @return true if there is a previous month that can be shown
+ */
+ public boolean canGoBack() {
+ return pager.getCurrentItem() > 0;
}
+ /**
+ * Pass all touch events to the pager so scrolling works on the edges of the calendar view.
+ */
@Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(showOtherDates);
- out.writeByte((byte) (allowClickDaysOutsideCurrentMonth ? 1 : 0));
- out.writeParcelable(minDate, 0);
- out.writeParcelable(maxDate, 0);
- out.writeTypedList(selectedDates);
- out.writeInt(topbarVisible ? 1 : 0);
- out.writeInt(selectionMode);
- out.writeInt(dynamicHeightEnabled ? 1 : 0);
- out.writeParcelable(currentMonth, 0);
- out.writeByte((byte) (cacheCurrentPosition ? 1 : 0));
- }
-
- public static final Parcelable.Creator CREATOR
- = new Parcelable.Creator() {
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
-
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
+ public boolean onTouchEvent(MotionEvent event) {
+ return pager.dispatchTouchEvent(event);
+ }
- private SavedState(Parcel in) {
- super(in);
- showOtherDates = in.readInt();
- allowClickDaysOutsideCurrentMonth = in.readByte() != 0;
- ClassLoader loader = CalendarDay.class.getClassLoader();
- minDate = in.readParcelable(loader);
- maxDate = in.readParcelable(loader);
- in.readTypedList(selectedDates, CalendarDay.CREATOR);
- topbarVisible = in.readInt() == 1;
- selectionMode = in.readInt();
- dynamicHeightEnabled = in.readInt() == 1;
- currentMonth = in.readParcelable(loader);
- cacheCurrentPosition = in.readByte() != 0;
- }
- }
-
- private static int getThemeAccentColor(Context context) {
- int colorAttr;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- colorAttr = android.R.attr.colorAccent;
- } else {
- //Get colorAccent defined for AppCompat
- colorAttr =
- context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
- }
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(colorAttr, outValue, true);
- return outValue.data;
- }
-
- /**
- * @return The first day of the week as a {@linkplain Calendar} day constant.
- */
- public DayOfWeek getFirstDayOfWeek() {
- return firstDayOfWeek;
- }
-
- /**
- * By default, the calendar will take up all the space needed to show any month (6 rows).
- * By enabling dynamic height, the view will change height dependant on the visible month.
- *
- * This means months that only need 5 or 4 rows to show the entire month will only take up
- * that many rows, and will grow and shrink as necessary.
- *
- * @param useDynamicHeight true to have the view different heights based on the visible month
- */
- public void setDynamicHeightEnabled(boolean useDynamicHeight) {
- this.mDynamicHeightEnabled = useDynamicHeight;
- }
-
- /**
- * @return the dynamic height state - true if enabled.
- */
- public boolean isDynamicHeightEnabled() {
- return mDynamicHeightEnabled;
- }
-
- /**
- * Add a collection of day decorators
- *
- * @param decorators decorators to add
- */
- public void addDecorators(Collection extends DayViewDecorator> decorators) {
- if (decorators == null) {
- return;
- }
-
- dayViewDecorators.addAll(decorators);
- adapter.setDecorators(dayViewDecorators);
- }
-
- /**
- * Add several day decorators
- *
- * @param decorators decorators to add
- */
- public void addDecorators(DayViewDecorator... decorators) {
- addDecorators(Arrays.asList(decorators));
- }
-
- /**
- * Add a day decorator
- *
- * @param decorator decorator to add
- */
- public void addDecorator(DayViewDecorator decorator) {
- if (decorator == null) {
- return;
- }
- dayViewDecorators.add(decorator);
- adapter.setDecorators(dayViewDecorators);
- }
-
- /**
- * Remove all decorators
- */
- public void removeDecorators() {
- dayViewDecorators.clear();
- adapter.setDecorators(dayViewDecorators);
- }
-
- /**
- * Remove a specific decorator instance. Same rules as {@linkplain List#remove(Object)}
- *
- * @param decorator decorator to remove
- */
- public void removeDecorator(DayViewDecorator decorator) {
- dayViewDecorators.remove(decorator);
- adapter.setDecorators(dayViewDecorators);
- }
-
- /**
- * Invalidate decorators after one has changed internally. That is, if a decorator mutates, you
- * should call this method to update the widget.
- */
- public void invalidateDecorators() {
- adapter.invalidateDecorators();
- }
-
- /*
- * Listener/Callback Code
- */
-
- /**
- * Sets the listener to be notified upon selected date changes.
- *
- * @param listener thing to be notified
- */
- public void setOnDateChangedListener(OnDateSelectedListener listener) {
- this.listener = listener;
- }
-
- /**
- * Sets the listener to be notified upon long clicks on dates.
- *
- * @param longClickListener thing to be notified
- */
- public void setOnDateLongClickListener(OnDateLongClickListener longClickListener) {
- this.longClickListener = longClickListener;
- }
-
- /**
- * Sets the listener to be notified upon month changes.
- *
- * @param listener thing to be notified
- */
- public void setOnMonthChangedListener(OnMonthChangedListener listener) {
- this.monthListener = listener;
- }
-
- /**
- * Sets the listener to be notified upon a range has been selected.
- *
- * @param listener thing to be notified
- */
- public void setOnRangeSelectedListener(OnRangeSelectedListener listener) {
- this.rangeListener = listener;
- }
-
- /**
- * Add listener to the title or null to remove it.
- *
- * @param listener Listener to be notified.
- */
- public void setOnTitleClickListener(final OnClickListener listener) {
- title.setOnClickListener(listener);
- }
-
- /**
- * Dispatch date change events to a listener, if set
- *
- * @param day the day that was selected
- * @param selected true if the day is now currently selected, false otherwise
- */
- protected void dispatchOnDateSelected(final CalendarDay day, final boolean selected) {
- if (listener != null) {
- listener.onDateSelected(MaterialCalendarView.this, day, selected);
- }
- }
-
- /**
- * Dispatch a range of days to a range listener, if set, ordered chronologically.
- *
- * @param days Enclosing days ordered from first to last day.
- */
- protected void dispatchOnRangeSelected(@NonNull final List days) {
- if (rangeListener != null) {
- rangeListener.onRangeSelected(MaterialCalendarView.this, days);
- }
- }
-
- /**
- * Dispatch date change events to a listener, if set
- *
- * @param day first day of the new month
- */
- protected void dispatchOnMonthChanged(final CalendarDay day) {
- if (monthListener != null) {
- monthListener.onMonthChanged(MaterialCalendarView.this, day);
- }
- }
-
- /**
- * Call by {@link CalendarPagerView} to indicate that a day was clicked and we should handle it.
- * This method will always process the click to the selected date.
- *
- * @param date date of the day that was clicked
- * @param nowSelected true if the date is now selected, false otherwise
- */
- protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) {
- switch (selectionMode) {
- case SELECTION_MODE_MULTIPLE: {
- adapter.setDateSelected(date, nowSelected);
- dispatchOnDateSelected(date, nowSelected);
- }
- break;
- case SELECTION_MODE_RANGE: {
- final List currentSelection = adapter.getSelectedDates();
-
- if (currentSelection.size() == 0) {
- // Selecting the first date of a range
- adapter.setDateSelected(date, nowSelected);
- dispatchOnDateSelected(date, nowSelected);
- } else if (currentSelection.size() == 1) {
- // Selecting the second date of a range
- final CalendarDay firstDaySelected = currentSelection.get(0);
- if (firstDaySelected.equals(date)) {
- // Right now, we are not supporting a range of one day, so we are removing the day instead.
- adapter.setDateSelected(date, nowSelected);
- dispatchOnDateSelected(date, nowSelected);
- } else if (firstDaySelected.isAfter(date)) {
- // Selecting a range, dispatching in reverse order...
- adapter.selectRange(date, firstDaySelected);
- dispatchOnRangeSelected(adapter.getSelectedDates());
- } else {
- // Selecting a range, dispatching in order...
- adapter.selectRange(firstDaySelected, date);
- dispatchOnRangeSelected(adapter.getSelectedDates());
- }
- } else {
- // Clearing selection and making a selection of the new date.
- adapter.clearSelections();
- adapter.setDateSelected(date, nowSelected);
- dispatchOnDateSelected(date, nowSelected);
+ /**
+ * @return the color used for the selection
+ */
+ public int getSelectionColor() {
+ return accentColor;
+ }
+
+ /**
+ * @param color The selection color
+ */
+ public void setSelectionColor(int color) {
+ if (color == 0) {
+ if (!isInEditMode()) {
+ return;
+ } else {
+ color = Color.GRAY;
+ }
}
- }
- break;
- default:
- case SELECTION_MODE_SINGLE: {
- adapter.clearSelections();
- adapter.setDateSelected(date, true);
- dispatchOnDateSelected(date, true);
- }
- break;
- }
- }
-
- /**
- * Select a fresh range of date including first day and last day.
- *
- * @param firstDay first day of the range to select
- * @param lastDay last day of the range to select
- */
- public void selectRange(final CalendarDay firstDay, final CalendarDay lastDay) {
- if (firstDay == null || lastDay == null) {
- return;
- } else if (firstDay.isAfter(lastDay)) {
- adapter.selectRange(lastDay, firstDay);
- dispatchOnRangeSelected(adapter.getSelectedDates());
- } else {
- adapter.selectRange(firstDay, lastDay);
- dispatchOnRangeSelected(adapter.getSelectedDates());
- }
- }
-
- /**
- * Call by {@link CalendarPagerView} to indicate that a day was clicked and we should handle it
- */
- protected void onDateClicked(final DayView dayView) {
- final CalendarDay currentDate = getCurrentDate();
- final CalendarDay selectedDate = dayView.getDate();
- final int currentMonth = currentDate.getMonth();
- final int selectedMonth = selectedDate.getMonth();
-
- if (calendarMode == CalendarMode.MONTHS
- && allowClickDaysOutsideCurrentMonth
- && currentMonth != selectedMonth) {
- if (currentDate.isAfter(selectedDate)) {
- goToPrevious();
- } else if (currentDate.isBefore(selectedDate)) {
- goToNext();
- }
- }
- onDateClicked(dayView.getDate(), !dayView.isChecked());
- }
-
- /**
- * Call by {@link CalendarPagerView} to indicate that a day was long clicked and we should handle
- * it
- */
- protected void onDateLongClicked(final DayView dayView) {
- if (longClickListener != null) {
- longClickListener.onDateLongClick(MaterialCalendarView.this, dayView.getDate());
- }
- }
-
- /**
- * Called by the adapter for cases when changes in state result in dates being unselected
- *
- * @param date date that should be de-selected
- */
- protected void onDateUnselected(CalendarDay date) {
- dispatchOnDateSelected(date, false);
- }
-
- /*
- * Show Other Dates Utils
- */
-
- /**
- * @param showOtherDates int flag for show other dates
- * @return true if the other months flag is set
- */
- public static boolean showOtherMonths(@ShowOtherDates int showOtherDates) {
- return (showOtherDates & SHOW_OTHER_MONTHS) != 0;
- }
-
- /**
- * @param showOtherDates int flag for show other dates
- * @return true if the out of range flag is set
- */
- public static boolean showOutOfRange(@ShowOtherDates int showOtherDates) {
- return (showOtherDates & SHOW_OUT_OF_RANGE) != 0;
- }
-
- /**
- * @param showOtherDates int flag for show other dates
- * @return true if the decorated disabled flag is set
- */
- public static boolean showDecoratedDisabled(@ShowOtherDates int showOtherDates) {
- return (showOtherDates & SHOW_DECORATED_DISABLED) != 0;
- }
-
- /*
- * Custom ViewGroup Code
- */
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected LayoutParams generateDefaultLayoutParams() {
- return new LayoutParams(1);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- final int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
- final int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
- final int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
- final int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
-
- //We need to disregard padding for a while. This will be added back later
- final int desiredWidth = specWidthSize - getPaddingLeft() - getPaddingRight();
- final int desiredHeight = specHeightSize - getPaddingTop() - getPaddingBottom();
-
- final int weekCount = getWeekCountBasedOnMode();
-
- final int viewTileHeight = getTopbarVisible() ? (weekCount + 1) : weekCount;
-
- //Calculate independent tile sizes for later
- int desiredTileWidth = desiredWidth / DEFAULT_DAYS_IN_WEEK;
- int desiredTileHeight = desiredHeight / viewTileHeight;
-
- int measureTileSize = -1;
- int measureTileWidth = -1;
- int measureTileHeight = -1;
-
- if (this.tileWidth != INVALID_TILE_DIMENSION || this.tileHeight != INVALID_TILE_DIMENSION) {
- if (this.tileWidth > 0) {
- //We have a tileWidth set, we should use that
- measureTileWidth = this.tileWidth;
- } else {
- measureTileWidth = desiredTileWidth;
- }
- if (this.tileHeight > 0) {
- //We have a tileHeight set, we should use that
- measureTileHeight = this.tileHeight;
- } else {
- measureTileHeight = desiredTileHeight;
- }
- } else if (specWidthMode == MeasureSpec.EXACTLY || specWidthMode == MeasureSpec.AT_MOST) {
- if (specHeightMode == MeasureSpec.EXACTLY) {
- //Pick the smaller of the two explicit sizes
- measureTileSize = Math.min(desiredTileWidth, desiredTileHeight);
- } else {
- //Be the width size the user wants
- measureTileSize = desiredTileWidth;
- }
- } else if (specHeightMode == MeasureSpec.EXACTLY || specHeightMode == MeasureSpec.AT_MOST) {
- //Be the height size the user wants
- measureTileSize = desiredTileHeight;
- }
-
- if (measureTileSize > 0) {
- //Use measureTileSize if set
- measureTileHeight = measureTileSize;
- measureTileWidth = measureTileSize;
- } else if (measureTileSize <= 0) {
- if (measureTileWidth <= 0) {
- //Set width to default if no value were set
- measureTileWidth = dpToPx(DEFAULT_TILE_SIZE_DP);
- }
- if (measureTileHeight <= 0) {
- //Set height to default if no value were set
- measureTileHeight = dpToPx(DEFAULT_TILE_SIZE_DP);
- }
- }
-
- //Calculate our size based off our measured tile size
- int measuredWidth = measureTileWidth * DEFAULT_DAYS_IN_WEEK;
- int measuredHeight = measureTileHeight * viewTileHeight;
-
- //Put padding back in from when we took it away
- measuredWidth += getPaddingLeft() + getPaddingRight();
- measuredHeight += getPaddingTop() + getPaddingBottom();
-
- //Contract fulfilled, setting out measurements
- setMeasuredDimension(
- //We clamp inline because we want to use un-clamped versions on the children
- clampSize(measuredWidth, widthMeasureSpec),
- clampSize(measuredHeight, heightMeasureSpec)
- );
-
- int count = getChildCount();
-
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
-
- LayoutParams p = (LayoutParams) child.getLayoutParams();
-
- int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
- DEFAULT_DAYS_IN_WEEK * measureTileWidth,
- MeasureSpec.EXACTLY
- );
-
- int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
- p.height * measureTileHeight,
- MeasureSpec.EXACTLY
- );
-
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
- }
- }
-
- private int getWeekCountBasedOnMode() {
- int weekCount = calendarMode.visibleWeeksCount;
- final boolean isInMonthsMode = calendarMode.equals(CalendarMode.MONTHS);
- if (isInMonthsMode && mDynamicHeightEnabled && adapter != null && pager != null) {
- final LocalDate cal = adapter.getItem(pager.getCurrentItem()).getDate();
- final LocalDate tempLastDay = cal.withDayOfMonth(cal.lengthOfMonth());
- weekCount = tempLastDay.get(WeekFields.of(firstDayOfWeek, 1).weekOfMonth());
- }
- return showWeekDays ? weekCount + DAY_NAMES_ROW : weekCount;
- }
-
- /**
- * Clamp the size to the measure spec.
- *
- * @param size Size we want to be
- * @param spec Measure spec to clamp against
- * @return the appropriate size to pass to {@linkplain View#setMeasuredDimension(int, int)}
- */
- private static int clampSize(int size, int spec) {
- int specMode = MeasureSpec.getMode(spec);
- int specSize = MeasureSpec.getSize(spec);
- switch (specMode) {
- case MeasureSpec.EXACTLY: {
- return specSize;
- }
- case MeasureSpec.AT_MOST: {
- return Math.min(size, specSize);
- }
- case MeasureSpec.UNSPECIFIED:
- default: {
- return size;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final int count = getChildCount();
-
- final int parentLeft = getPaddingLeft();
- final int parentWidth = right - left - parentLeft - getPaddingRight();
-
- int childTop = getPaddingTop();
-
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.getVisibility() == View.GONE) {
- continue;
- }
-
- final int width = child.getMeasuredWidth();
- final int height = child.getMeasuredHeight();
-
- int delta = (parentWidth - width) / 2;
- int childLeft = parentLeft + delta;
-
- child.layout(childLeft, childTop, childLeft + width, childTop + height);
-
- childTop += height;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public LayoutParams generateLayoutParams(AttributeSet attrs) {
- return new LayoutParams(1);
- }
-
- @Override
- public boolean shouldDelayChildPressedState() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
- return p instanceof LayoutParams;
- }
-
- @Override
- protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
- return new LayoutParams(1);
- }
-
- @Override
- public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- event.setClassName(MaterialCalendarView.class.getName());
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.setClassName(MaterialCalendarView.class.getName());
- }
-
- /**
- * Simple layout params for MaterialCalendarView. The only variation for layout is height.
- */
- protected static class LayoutParams extends MarginLayoutParams {
-
- /**
- * Create a layout that matches parent width, and is X number of tiles high
+ accentColor = color;
+ adapter.setSelectionColor(color);
+ invalidate();
+ }
+
+ /**
+ * Set content description for button past
*
- * @param tileHeight view height in number of tiles
- */
- public LayoutParams(int tileHeight) {
- super(MATCH_PARENT, tileHeight);
- }
- }
-
- /**
- * Enable or disable the ability to swipe between months.
- *
- * @param pagingEnabled pass false to disable paging, true to enable (default)
- */
- public void setPagingEnabled(boolean pagingEnabled) {
- pager.setPagingEnabled(pagingEnabled);
- updateUi();
- }
-
- /**
- * @return true if swiping months is enabled, false if disabled. Default is true.
- */
- public boolean isPagingEnabled() {
- return pager.isPagingEnabled();
- }
-
- /**
- * Preserve the current parameters of the Material Calendar View.
- */
- public State state() {
- return state;
- }
-
- /**
- * Initialize the parameters from scratch.
- */
- public StateBuilder newState() {
- return new StateBuilder();
- }
-
- public class State {
- private final CalendarMode calendarMode;
- private final DayOfWeek firstDayOfWeek;
- private final CalendarDay minDate;
- private final CalendarDay maxDate;
- private final boolean cacheCurrentPosition;
- private final boolean showWeekDays;
-
- private State(final StateBuilder builder) {
- calendarMode = builder.calendarMode;
- firstDayOfWeek = builder.firstDayOfWeek;
- minDate = builder.minDate;
- maxDate = builder.maxDate;
- cacheCurrentPosition = builder.cacheCurrentPosition;
- showWeekDays = builder.showWeekDays;
- }
-
- /**
- * Modify parameters from current state.
- */
- public StateBuilder edit() {
- return new StateBuilder(this);
- }
- }
-
- public class StateBuilder {
- private CalendarMode calendarMode;
- private DayOfWeek firstDayOfWeek;
- private boolean cacheCurrentPosition = false;
- private CalendarDay minDate = null;
- private CalendarDay maxDate = null;
- private boolean showWeekDays;
+ * @param description String to use as content description
+ */
+ public void setContentDescriptionArrowPast(final CharSequence description) {
+ backArrowButton.setContentDescription(description);
+ }
- public StateBuilder() {
- calendarMode = CalendarMode.MONTHS;
- firstDayOfWeek =
- LocalDate.now().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 1).getDayOfWeek();
+ /**
+ * Set content description for button future
+ *
+ * @param description String to use as content description
+ */
+ public void setContentDescriptionArrowFuture(final CharSequence description) {
+ ForwardArrowButton.setContentDescription(description);
}
- private StateBuilder(final State state) {
- calendarMode = state.calendarMode;
- firstDayOfWeek = state.firstDayOfWeek;
- minDate = state.minDate;
- maxDate = state.maxDate;
- cacheCurrentPosition = state.cacheCurrentPosition;
- showWeekDays = state.showWeekDays;
+ /**
+ * Set content description for calendar
+ *
+ * @param description String to use as content description
+ */
+ public void setContentDescriptionCalendar(final CharSequence description) {
+ calendarContentDescription = description;
}
/**
- * Sets the first day of the week.
- *
- * Uses the {@link DayOfWeek} day constants.
+ * Get content description for calendar
*
- * @param day The first day of the week as a {@link DayOfWeek} enum.
- * @see java.util.Calendar
+ * @return calendar's content description
*/
- public StateBuilder setFirstDayOfWeek(DayOfWeek day) {
- this.firstDayOfWeek = day;
- return this;
+ public CharSequence getCalendarContentDescription() {
+ return calendarContentDescription != null
+ ? calendarContentDescription
+ : getContext().getString(R.string.calendar);
}
/**
- * Set calendar display mode. The default mode is Months.
- * When switching between modes will select todays date, or the selected date,
- * if selection mode is single.
+ * Set a formatter for day content description.
*
- * @param mode - calendar mode
+ * @param formatter the new formatter, null for default
*/
- public StateBuilder setCalendarDisplayMode(CalendarMode mode) {
- this.calendarMode = mode;
- return this;
+ public void setDayFormatterContentDescription(DayFormatter formatter) {
+ adapter.setDayFormatterContentDescription(formatter);
}
/**
- * @param date set the minimum selectable date, null for no minimum
+ * @return icon used for the left arrow
*/
- public StateBuilder setMinimumDate(@Nullable LocalDate date) {
- setMinimumDate(CalendarDay.from(date));
- return this;
+ public Drawable getLeftArrow() {
+ return backArrowButton.getDrawable();
}
/**
- * @param calendar set the minimum selectable date, null for no minimum
+ * @param icon the new icon to use for the left paging arrow
*/
- public StateBuilder setMinimumDate(@Nullable CalendarDay calendar) {
- minDate = calendar;
- return this;
+ public void setLeftArrow(@DrawableRes final int icon) {
+ backArrowButton.setImageResource(icon);
}
/**
- * @param date set the maximum selectable date, null for no maximum
+ * @return icon used for the right arrow
*/
- public StateBuilder setMaximumDate(@Nullable LocalDate date) {
- setMaximumDate(CalendarDay.from(date));
- return this;
+ public Drawable getRightArrow() {
+ return ForwardArrowButton.getDrawable();
}
/**
- * @param calendar set the maximum selectable date, null for no maximum
+ * @param icon the new icon to use for the right paging arrow
*/
- public StateBuilder setMaximumDate(@Nullable CalendarDay calendar) {
- maxDate = calendar;
- return this;
+ public void setRightArrow(@DrawableRes final int icon) {
+ ForwardArrowButton.setImageResource(icon);
}
/**
- * @param showWeekDays true to show week days names
+ * @param resourceId The text appearance resource id.
*/
- public StateBuilder setShowWeekDays(boolean showWeekDays) {
- this.showWeekDays = showWeekDays;
- return this;
+ public void setHeaderTextAppearance(int resourceId) {
+ title.setTextAppearance(getContext(), resourceId);
}
/**
- * Use this method to enable saving the current position when switching
- * between week and month mode. By default, the calendar update to the latest selected date
- * or the current date. When set to true, the view will used the month that the calendar is
- * currently on.
+ * @param resourceId The text appearance resource id.
+ */
+ public void setDateTextAppearance(int resourceId) {
+ adapter.setDateTextAppearance(resourceId);
+ }
+
+ /**
+ * @param resourceId The text appearance resource id.
+ */
+ public void setWeekDayTextAppearance(int resourceId) {
+ adapter.setWeekDayTextAppearance(resourceId);
+ }
+
+ /**
+ * Get the currently selected date, or null if no selection. Depending on the selection mode,
+ * you might get different results.
+ *
+ *
For {@link #SELECTION_MODE_SINGLE}, returns the selected date.
+ *
For {@link #SELECTION_MODE_MULTIPLE}, returns the last date selected.
+ *
For {@link #SELECTION_MODE_RANGE}, returns the last date of the range. In most cases, you
+ * should probably be using {@link #getSelectedDates()}.
+ *
For {@link #SELECTION_MODE_NONE}, returns null.
+ *
+ * @return The selected day, or null if no selection. If in multiple selection mode, this
+ * will return the last date of the list of selected dates.
+ * @see MaterialCalendarView#getSelectedDates()
+ */
+ @Nullable
+ public CalendarDay getSelectedDate() {
+ List dates = adapter.getSelectedDates();
+ if (dates.isEmpty()) {
+ return null;
+ } else {
+ return dates.get(dates.size() - 1);
+ }
+ }
+
+ /**
+ * @param date a Date set to a day to select. Null to clear selection
+ */
+ public void setSelectedDate(@Nullable LocalDate date) {
+ setSelectedDate(CalendarDay.from(date));
+ }
+
+ /**
+ * @param date a Date to set as selected. Null to clear selection
+ */
+ public void setSelectedDate(@Nullable CalendarDay date) {
+ clearSelection();
+ if (date != null) {
+ setDateSelected(date, true);
+ }
+ }
+
+ /**
+ * Return the list of currently selected dates. Mostly useful for {@link #SELECTION_MODE_MULTIPLE}
+ * and {@link #SELECTION_MODE_RANGE}. For the other modes, check {@link #getSelectedDate()}.
*
- * @param cacheCurrentPosition Set to true to cache the current position, false otherwise.
- */
- public StateBuilder isCacheCalendarPositionEnabled(final boolean cacheCurrentPosition) {
- this.cacheCurrentPosition = cacheCurrentPosition;
- return this;
- }
-
- public void commit() {
- MaterialCalendarView.this.commit(new State(this));
- }
- }
-
- private void commit(State state) {
- // Use the calendarDayToShow to determine which date to focus on for the case of switching between month and week views
- CalendarDay calendarDayToShow = null;
- if (adapter != null && state.cacheCurrentPosition) {
- calendarDayToShow = adapter.getItem(pager.getCurrentItem());
- if (calendarMode != state.calendarMode) {
- CalendarDay currentlySelectedDate = getSelectedDate();
- if (calendarMode == CalendarMode.MONTHS && currentlySelectedDate != null) {
- // Going from months to weeks
- LocalDate lastVisibleCalendar = calendarDayToShow.getDate();
- CalendarDay lastVisibleCalendarDay = CalendarDay.from(lastVisibleCalendar.plusDays(1));
- if (currentlySelectedDate.equals(calendarDayToShow) ||
- (currentlySelectedDate.isAfter(calendarDayToShow) && currentlySelectedDate.isBefore(
- lastVisibleCalendarDay))) {
- // Currently selected date is within view, so center on that
- calendarDayToShow = currentlySelectedDate;
- }
- } else if (calendarMode == CalendarMode.WEEKS) {
- // Going from weeks to months
- LocalDate lastVisibleCalendar = calendarDayToShow.getDate();
- CalendarDay lastVisibleCalendarDay = CalendarDay.from(lastVisibleCalendar.plusDays(6));
- if (currentlySelectedDate != null &&
- (currentlySelectedDate.equals(calendarDayToShow) || currentlySelectedDate.equals(
- lastVisibleCalendarDay) ||
- (currentlySelectedDate.isAfter(calendarDayToShow)
- && currentlySelectedDate.isBefore(lastVisibleCalendarDay)))) {
- // Currently selected date is within view, so center on that
- calendarDayToShow = currentlySelectedDate;
- } else {
- calendarDayToShow = lastVisibleCalendarDay;
- }
+ *
For {@link #SELECTION_MODE_MULTIPLE}, returns the list in the order of selection.
+ *
For {@link #SELECTION_MODE_RANGE}, returns the range of dates ordered chronologically.
+ *
+ * @return All of the currently selected dates.
+ * @see MaterialCalendarView#getSelectedDate()
+ */
+ @NonNull
+ public List getSelectedDates() {
+ return adapter.getSelectedDates();
+ }
+
+ /**
+ * Clear the currently selected date(s)
+ */
+ public void clearSelection() {
+ List dates = getSelectedDates();
+ adapter.clearSelections();
+ for (CalendarDay day : dates) {
+ dispatchOnDateSelected(day, false);
+ }
+ }
+
+ /**
+ * @param day a CalendarDay to change. Passing null does nothing
+ * @param selected true if day should be selected, false to deselect
+ */
+ public void setDateSelected(@Nullable CalendarDay day, boolean selected) {
+ if (day == null) {
+ return;
}
- }
- }
-
- this.state = state;
- // Save states parameters
- calendarMode = state.calendarMode;
- firstDayOfWeek = state.firstDayOfWeek;
- minDate = state.minDate;
- maxDate = state.maxDate;
- showWeekDays = state.showWeekDays;
-
- // Recreate adapter
- final CalendarPagerAdapter> newAdapter;
- switch (calendarMode) {
- case MONTHS:
- newAdapter = new MonthPagerAdapter(this);
- break;
- case WEEKS:
- newAdapter = new WeekPagerAdapter(this);
- break;
- default:
- throw new IllegalArgumentException("Provided display mode which is not yet implemented");
- }
- if (adapter == null) {
- adapter = newAdapter;
- } else {
- adapter = adapter.migrateStateAndReturn(newAdapter);
- }
- adapter.setShowWeekDays(showWeekDays);
- pager.setAdapter(adapter);
- setRangeDates(minDate, maxDate);
-
- // Reset height params after mode change
- int tileHeight = showWeekDays ? calendarMode.visibleWeeksCount + DAY_NAMES_ROW
- : calendarMode.visibleWeeksCount;
- pager.setLayoutParams(new LayoutParams(tileHeight));
-
- setCurrentDate(
- selectionMode == SELECTION_MODE_SINGLE && !adapter.getSelectedDates().isEmpty()
- ? adapter.getSelectedDates().get(0)
- : CalendarDay.today());
-
- if (calendarDayToShow != null) {
- pager.setCurrentItem(adapter.getIndexForDay(calendarDayToShow));
- }
-
- invalidateDecorators();
- updateUi();
- }
-
- /**
- * Used for enabling or disabling views, while also changing the alpha.
- *
- * @param view The view to enable or disable.
- * @param enable Whether to enable or disable the view.
- */
- private static void enableView(final View view, final boolean enable) {
- view.setEnabled(enable);
- view.setAlpha(enable ? 1f : 0.1f);
- }
+ adapter.setDateSelected(day, selected);
+ }
+
+ /**
+ * Get the current first day of the month in month mode, or the first visible day of the
+ * currently visible week.
+ *
+ * For example, in week mode, if the week is July 29th, 2018 to August 4th, 2018,
+ * this will return July 29th, 2018. If in month mode and the month is august, then this method
+ * will return August 1st, 2018.
+ *
+ * @return The current month or week shown, will be set to first day of the month in month mode,
+ * or the first visible day for a week.
+ */
+ public CalendarDay getCurrentDate() {
+ return adapter.getItem(pager.getCurrentItem());
+ }
+
+ /**
+ * Set the calendar to a specific month or week based on a date.
+ *
+ * In month mode, the calendar will be set to the corresponding month.
+ *
+ * In week mode, the calendar will be set to the corresponding week.
+ *
+ * @param calendar a Calendar set to a day to focus the calendar on. Null will do nothing
+ */
+ public void setCurrentDate(@Nullable LocalDate calendar) {
+ setCurrentDate(CalendarDay.from(calendar));
+ }
+
+ /**
+ * Set the calendar to a specific month or week based on a date.
+ *
+ * In month mode, the calendar will be set to the corresponding month.
+ *
+ * In week mode, the calendar will be set to the corresponding week.
+ *
+ * @param day a CalendarDay to focus the calendar on. Null will do nothing
+ */
+ public void setCurrentDate(@Nullable CalendarDay day) {
+ setCurrentDate(day, true);
+ }
+
+ /**
+ * Set the calendar to a specific month or week based on a date.
+ *
+ * In month mode, the calendar will be set to the corresponding month.
+ *
+ * In week mode, the calendar will be set to the corresponding week.
+ *
+ * @param day a CalendarDay to focus the calendar on. Null will do nothing
+ * @param useSmoothScroll use smooth scroll when changing months.
+ */
+ public void setCurrentDate(@Nullable CalendarDay day, boolean useSmoothScroll) {
+ if (day == null) {
+ return;
+ }
+ int index = adapter.getIndexForDay(day);
+ pager.setCurrentItem(index, useSmoothScroll);
+ updateUi();
+ }
+
+ /**
+ * @return the minimum selectable date for the calendar, if any
+ */
+ public CalendarDay getMinimumDate() {
+ return minDate;
+ }
+
+ /**
+ * @return the maximum selectable date for the calendar, if any
+ */
+ public CalendarDay getMaximumDate() {
+ return maxDate;
+ }
+
+ /**
+ * Allow the user to click on dates from other months that are not out of range. Go to next or
+ * previous month if a day outside the current month is clicked. The day still need to be
+ * enabled to be selected.
+ * Default value is true. Should be used with {@link #SHOW_OTHER_MONTHS}.
+ *
+ * @param enabled True to allow the user to click on a day outside current month displayed
+ */
+ public void setAllowClickDaysOutsideCurrentMonth(final boolean enabled) {
+ this.allowClickDaysOutsideCurrentMonth = enabled;
+ }
+
+ /**
+ * Set a formatter for weekday labels.
+ *
+ * @param formatter the new formatter, null for default
+ */
+ public void setWeekDayFormatter(WeekDayFormatter formatter) {
+ adapter.setWeekDayFormatter(formatter == null ? WeekDayFormatter.DEFAULT : formatter);
+ }
+
+ /**
+ * Set a formatter for day labels.
+ *
+ * @param formatter the new formatter, null for default
+ */
+ public void setDayFormatter(DayFormatter formatter) {
+ adapter.setDayFormatter(formatter == null ? DateFormatDayFormatter.getInstance() : formatter);
+ }
+
+ /**
+ * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.WeekDayFormatter}
+ * with the provided week day labels
+ *
+ * @param weekDayLabels Labels to use for the days of the week
+ * @see com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter
+ * @see #setWeekDayFormatter(com.prolificinteractive.materialcalendarview.format.WeekDayFormatter)
+ */
+ public void setWeekDayLabels(CharSequence[] weekDayLabels) {
+ setWeekDayFormatter(new ArrayWeekDayFormatter(weekDayLabels));
+ }
+
+ /**
+ * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.WeekDayFormatter}
+ * with the provided week day labels
+ *
+ * @param arrayRes String array resource of week day labels
+ * @see com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter
+ * @see #setWeekDayFormatter(com.prolificinteractive.materialcalendarview.format.WeekDayFormatter)
+ */
+ public void setWeekDayLabels(@ArrayRes int arrayRes) {
+ setWeekDayLabels(getResources().getTextArray(arrayRes));
+ }
+
+ /**
+ * @return int of flags used for showing non-enabled dates
+ * @see #SHOW_ALL
+ * @see #SHOW_NONE
+ * @see #SHOW_DEFAULTS
+ * @see #SHOW_OTHER_MONTHS
+ * @see #SHOW_OUT_OF_RANGE
+ * @see #SHOW_DECORATED_DISABLED
+ */
+ @ShowOtherDates
+ public int getShowOtherDates() {
+ return adapter.getShowOtherDates();
+ }
+
+ /**
+ * The default value is {@link #SHOW_DEFAULTS}, which currently is just {@link
+ * #SHOW_DECORATED_DISABLED}.
+ * This means that the default visible days are of the current month, in the min-max range.
+ *
+ * @param showOtherDates flags for showing non-enabled dates
+ * @see #SHOW_ALL
+ * @see #SHOW_NONE
+ * @see #SHOW_DEFAULTS
+ * @see #SHOW_OTHER_MONTHS
+ * @see #SHOW_OUT_OF_RANGE
+ * @see #SHOW_DECORATED_DISABLED
+ */
+ public void setShowOtherDates(@ShowOtherDates int showOtherDates) {
+ adapter.setShowOtherDates(showOtherDates);
+ }
+
+ /**
+ * @return true if allow click on days outside current month displayed
+ */
+ public boolean allowClickDaysOutsideCurrentMonth() {
+ return allowClickDaysOutsideCurrentMonth;
+ }
+
+ /**
+ * @return true if the week days names are shown
+ */
+ public boolean isShowWeekDays() {
+ return showWeekDays;
+ }
+
+ /**
+ * Set a custom formatter for the month/year title
+ *
+ * @param titleFormatter new formatter to use, null to use default formatter
+ */
+ public void setTitleFormatter(@Nullable TitleFormatter titleFormatter) {
+ titleChanger.setTitleFormatter(titleFormatter);
+ adapter.setTitleFormatter(titleFormatter);
+ updateUi();
+ }
+
+ /**
+ * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.TitleFormatter}
+ * using the provided month labels
+ *
+ * @param monthLabels month labels to use
+ * @see com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter
+ * @see #setTitleFormatter(com.prolificinteractive.materialcalendarview.format.TitleFormatter)
+ */
+ public void setTitleMonths(CharSequence[] monthLabels) {
+ setTitleFormatter(new MonthArrayTitleFormatter(monthLabels));
+ }
+
+ /**
+ * Set a {@linkplain com.prolificinteractive.materialcalendarview.format.TitleFormatter}
+ * using the provided month labels
+ *
+ * @param arrayRes String array resource of month labels to use
+ * @see com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter
+ * @see #setTitleFormatter(com.prolificinteractive.materialcalendarview.format.TitleFormatter)
+ */
+ public void setTitleMonths(@ArrayRes int arrayRes) {
+ setTitleMonths(getResources().getTextArray(arrayRes));
+ }
+
+ /**
+ * Get the orientation of the animation of the title.
+ *
+ * @return Title animation orientation {@link MaterialCalendarView#VERTICAL} or {@link
+ * MaterialCalendarView#HORIZONTAL}
+ */
+ public int getTitleAnimationOrientation() {
+ return titleChanger.getOrientation();
+ }
+
+ /**
+ * Change the title animation orientation to have a different look and feel.
+ *
+ * @param orientation {@link MaterialCalendarView#VERTICAL} or {@link
+ * MaterialCalendarView#HORIZONTAL}
+ */
+ public void setTitleAnimationOrientation(final int orientation) {
+ titleChanger.setOrientation(orientation);
+ }
+
+ /**
+ * @return true if the topbar is visible
+ */
+ public boolean getTopbarVisible() {
+ return topbar.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * Sets the visibility {@link #topbar}, which contains
+ * the previous month button {@link #backArrowButton}, next month button {@link #ForwardArrowButton},
+ * and the month title {@link #title}.
+ *
+ * @param visible Boolean indicating if the topbar is visible
+ */
+ public void setTopbarVisible(boolean visible) {
+ topbar.setVisibility(visible ? View.VISIBLE : View.GONE);
+ requestLayout();
+ }
+
+ /**
+ * Get the current {@link CalendarMode} set of the Calendar.
+ *
+ * @return Whichever mode the calendar is currently in.
+ */
+ public CalendarMode getCalendarMode() {
+ return calendarMode;
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ SavedState ss = new SavedState(super.onSaveInstanceState());
+ ss.showOtherDates = getShowOtherDates();
+ ss.allowClickDaysOutsideCurrentMonth = allowClickDaysOutsideCurrentMonth();
+ ss.minDate = getMinimumDate();
+ ss.maxDate = getMaximumDate();
+ ss.selectedDates = getSelectedDates();
+ ss.selectionMode = getSelectionMode();
+ ss.topbarVisible = getTopbarVisible();
+ ss.dynamicHeightEnabled = mDynamicHeightEnabled;
+ ss.currentMonth = currentMonth;
+ ss.cacheCurrentPosition = state.cacheCurrentPosition;
+ return ss;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ state().edit()
+ .setMinimumDate(ss.minDate)
+ .setMaximumDate(ss.maxDate)
+ .isCacheCalendarPositionEnabled(ss.cacheCurrentPosition)
+ .commit();
+
+ setShowOtherDates(ss.showOtherDates);
+ setAllowClickDaysOutsideCurrentMonth(ss.allowClickDaysOutsideCurrentMonth);
+ clearSelection();
+ for (CalendarDay calendarDay : ss.selectedDates) {
+ setDateSelected(calendarDay, true);
+ }
+ setTopbarVisible(ss.topbarVisible);
+ setSelectionMode(ss.selectionMode);
+ setDynamicHeightEnabled(ss.dynamicHeightEnabled);
+ setCurrentDate(ss.currentMonth);
+ }
+
+ @Override
+ protected void dispatchSaveInstanceState(@NonNull SparseArray container) {
+ dispatchFreezeSelfOnly(container);
+ }
+
+ @Override
+ protected void dispatchRestoreInstanceState(@NonNull SparseArray container) {
+ dispatchThawSelfOnly(container);
+ }
+
+ private void setRangeDates(CalendarDay min, CalendarDay max) {
+ CalendarDay c = currentMonth;
+ adapter.setRangeDates(min, max);
+ currentMonth = c;
+ if (min != null) {
+ currentMonth = min.isAfter(currentMonth) ? min : currentMonth;
+ }
+ int position = adapter.getIndexForDay(c);
+ pager.setCurrentItem(position, false);
+ updateUi();
+ }
+
+ /**
+ * @return The first day of the week as a {@linkplain Calendar} day constant.
+ */
+ public DayOfWeek getFirstDayOfWeek() {
+ return firstDayOfWeek;
+ }
+
+ /**
+ * @return the dynamic height state - true if enabled.
+ */
+ public boolean isDynamicHeightEnabled() {
+ return mDynamicHeightEnabled;
+ }
+
+ /**
+ * By default, the calendar will take up all the space needed to show any month (6 rows).
+ * By enabling dynamic height, the view will change height dependant on the visible month.
+ *
+ * This means months that only need 5 or 4 rows to show the entire month will only take up
+ * that many rows, and will grow and shrink as necessary.
+ *
+ * @param useDynamicHeight true to have the view different heights based on the visible month
+ */
+ public void setDynamicHeightEnabled(boolean useDynamicHeight) {
+ this.mDynamicHeightEnabled = useDynamicHeight;
+ }
+
+ /**
+ * Add a collection of day decorators
+ *
+ * @param decorators decorators to add
+ */
+ public void addDecorators(Collection extends DayViewDecorator> decorators) {
+ if (decorators == null) {
+ return;
+ }
+
+ dayViewDecorators.addAll(decorators);
+ adapter.setDecorators(dayViewDecorators);
+ }
+
+ /**
+ * Add several day decorators
+ *
+ * @param decorators decorators to add
+ */
+ public void addDecorators(DayViewDecorator... decorators) {
+ addDecorators(Arrays.asList(decorators));
+ }
+
+ /**
+ * Add a day decorator
+ *
+ * @param decorator decorator to add
+ */
+ public void addDecorator(DayViewDecorator decorator) {
+ if (decorator == null) {
+ return;
+ }
+ dayViewDecorators.add(decorator);
+ adapter.setDecorators(dayViewDecorators);
+ }
+
+ /**
+ * Remove all decorators
+ */
+ public void removeDecorators() {
+ dayViewDecorators.clear();
+ adapter.setDecorators(dayViewDecorators);
+ }
+
+ /*
+ * Listener/Callback Code
+ */
+
+ /**
+ * Remove a specific decorator instance. Same rules as {@linkplain List#remove(Object)}
+ *
+ * @param decorator decorator to remove
+ */
+ public void removeDecorator(DayViewDecorator decorator) {
+ dayViewDecorators.remove(decorator);
+ adapter.setDecorators(dayViewDecorators);
+ }
+
+ /**
+ * Invalidate decorators after one has changed internally. That is, if a decorator mutates, you
+ * should call this method to update the widget.
+ */
+ public void invalidateDecorators() {
+ adapter.invalidateDecorators();
+ }
+
+ /**
+ * Sets the listener to be notified upon selected date changes.
+ *
+ * @param listener thing to be notified
+ */
+ public void setOnDateChangedListener(OnDateSelectedListener listener) {
+ this.listener = listener;
+ }
+
+ /**
+ * Sets the listener to be notified upon long clicks on dates.
+ *
+ * @param longClickListener thing to be notified
+ */
+ public void setOnDateLongClickListener(OnDateLongClickListener longClickListener) {
+ this.longClickListener = longClickListener;
+ }
+
+ /**
+ * Sets the listener to be notified upon month changes.
+ *
+ * @param listener thing to be notified
+ */
+ public void setOnMonthChangedListener(OnMonthChangedListener listener) {
+ this.monthListener = listener;
+ }
+
+ /**
+ * Sets the listener to be notified upon a range has been selected.
+ *
+ * @param listener thing to be notified
+ */
+ public void setOnRangeSelectedListener(OnRangeSelectedListener listener) {
+ this.rangeListener = listener;
+ }
+
+ /**
+ * Add listener to the title or null to remove it.
+ *
+ * @param listener Listener to be notified.
+ */
+ public void setOnTitleClickListener(final OnClickListener listener) {
+ title.setOnClickListener(listener);
+ }
+
+ /**
+ * Dispatch date change events to a listener, if set
+ *
+ * @param day the day that was selected
+ * @param selected true if the day is now currently selected, false otherwise
+ */
+ protected void dispatchOnDateSelected(final CalendarDay day, final boolean selected) {
+ if (listener != null) {
+ listener.onDateSelected(MaterialCalendarView.this, day, selected);
+ }
+ }
+
+ /**
+ * Dispatch a range of days to a range listener, if set, ordered chronologically.
+ *
+ * @param days Enclosing days ordered from first to last day.
+ */
+ protected void dispatchOnRangeSelected(@NonNull final List days) {
+ if (rangeListener != null) {
+ rangeListener.onRangeSelected(MaterialCalendarView.this, days);
+ }
+ }
+
+ /**
+ * Dispatch date change events to a listener, if set
+ *
+ * @param day first day of the new month
+ */
+ protected void dispatchOnMonthChanged(final CalendarDay day) {
+ if (monthListener != null) {
+ monthListener.onMonthChanged(MaterialCalendarView.this, day);
+ }
+ }
+
+ /**
+ * Call by {@link CalendarPagerView} to indicate that a day was clicked and we should handle it.
+ * This method will always process the click to the selected date.
+ *
+ * @param date date of the day that was clicked
+ * @param nowSelected true if the date is now selected, false otherwise
+ */
+ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) {
+ switch (selectionMode) {
+ case SELECTION_MODE_MULTIPLE: {
+ adapter.setDateSelected(date, nowSelected);
+ dispatchOnDateSelected(date, nowSelected);
+ }
+ break;
+ case SELECTION_MODE_RANGE: {
+ final List currentSelection = adapter.getSelectedDates();
+
+ if (currentSelection.size() == 0) {
+ // Selecting the first date of a range
+ adapter.setDateSelected(date, nowSelected);
+ dispatchOnDateSelected(date, nowSelected);
+ } else if (currentSelection.size() == 1) {
+ // Selecting the second date of a range
+ final CalendarDay firstDaySelected = currentSelection.get(0);
+ if (firstDaySelected.equals(date)) {
+ // Right now, we are not supporting a range of one day, so we are removing the day instead.
+ adapter.setDateSelected(date, nowSelected);
+ dispatchOnDateSelected(date, nowSelected);
+ } else if (firstDaySelected.isAfter(date)) {
+ // Selecting a range, dispatching in reverse order...
+ adapter.selectRange(date, firstDaySelected);
+ dispatchOnRangeSelected(adapter.getSelectedDates());
+ } else {
+ // Selecting a range, dispatching in order...
+ adapter.selectRange(firstDaySelected, date);
+ dispatchOnRangeSelected(adapter.getSelectedDates());
+ }
+ } else {
+ // Clearing selection and making a selection of the new date.
+ adapter.clearSelections();
+ adapter.setDateSelected(date, nowSelected);
+ dispatchOnDateSelected(date, nowSelected);
+ }
+ }
+ break;
+ default:
+ case SELECTION_MODE_SINGLE: {
+ adapter.clearSelections();
+ adapter.setDateSelected(date, true);
+ dispatchOnDateSelected(date, true);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Select a fresh range of date including first day and last day.
+ *
+ * @param firstDay first day of the range to select
+ * @param lastDay last day of the range to select
+ */
+ public void selectRange(final CalendarDay firstDay, final CalendarDay lastDay) {
+ if (firstDay == null || lastDay == null) {
+ return;
+ } else if (firstDay.isAfter(lastDay)) {
+ adapter.selectRange(lastDay, firstDay);
+ dispatchOnRangeSelected(adapter.getSelectedDates());
+ } else {
+ adapter.selectRange(firstDay, lastDay);
+ dispatchOnRangeSelected(adapter.getSelectedDates());
+ }
+ }
+
+ /**
+ * Call by {@link CalendarPagerView} to indicate that a day was clicked and we should handle it
+ */
+ protected void onDateClicked(final DayView dayView) {
+ final CalendarDay currentDate = getCurrentDate();
+ final CalendarDay selectedDate = dayView.getDate();
+ final int currentMonth = currentDate.getMonth();
+ final int selectedMonth = selectedDate.getMonth();
+
+ if (calendarMode == CalendarMode.MONTHS
+ && allowClickDaysOutsideCurrentMonth
+ && currentMonth != selectedMonth) {
+ if (currentDate.isAfter(selectedDate)) {
+ goToPrevious();
+ } else if (currentDate.isBefore(selectedDate)) {
+ goToNext();
+ }
+ }
+ onDateClicked(dayView.getDate(), !dayView.isChecked());
+ }
+
+ /*
+ * Show Other Dates Utils
+ */
+
+ /**
+ * Call by {@link CalendarPagerView} to indicate that a day was long clicked and we should handle
+ * it
+ */
+ protected void onDateLongClicked(final DayView dayView) {
+ if (longClickListener != null) {
+ longClickListener.onDateLongClick(MaterialCalendarView.this, dayView.getDate());
+ }
+ }
+
+ /**
+ * Called by the adapter for cases when changes in state result in dates being unselected
+ *
+ * @param date date that should be de-selected
+ */
+ protected void onDateUnselected(CalendarDay date) {
+ dispatchOnDateSelected(date, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(1);
+ }
+
+ /*
+ * Custom ViewGroup Code
+ */
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ final int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
+ final int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+ //We need to disregard padding for a while. This will be added back later
+ final int desiredWidth = specWidthSize - getPaddingLeft() - getPaddingRight();
+ final int desiredHeight = specHeightSize - getPaddingTop() - getPaddingBottom();
+
+ final int weekCount = getWeekCountBasedOnMode();
+
+ final int viewTileHeight = getTopbarVisible() ? (weekCount + 1) : weekCount;
+
+ //Calculate independent tile sizes for later
+ int desiredTileWidth = desiredWidth / DEFAULT_DAYS_IN_WEEK;
+ int desiredTileHeight = desiredHeight / viewTileHeight;
+
+ int measureTileSize = -1;
+ int measureTileWidth = -1;
+ int measureTileHeight = -1;
+
+ if (this.tileWidth != INVALID_TILE_DIMENSION || this.tileHeight != INVALID_TILE_DIMENSION) {
+ if (this.tileWidth > 0) {
+ //We have a tileWidth set, we should use that
+ measureTileWidth = this.tileWidth;
+ } else {
+ measureTileWidth = desiredTileWidth;
+ }
+ if (this.tileHeight > 0) {
+ //We have a tileHeight set, we should use that
+ measureTileHeight = this.tileHeight;
+ } else {
+ measureTileHeight = desiredTileHeight;
+ }
+ } else if (specWidthMode == MeasureSpec.EXACTLY || specWidthMode == MeasureSpec.AT_MOST) {
+ if (specHeightMode == MeasureSpec.EXACTLY) {
+ //Pick the smaller of the two explicit sizes
+ measureTileSize = Math.min(desiredTileWidth, desiredTileHeight);
+ } else {
+ //Be the width size the user wants
+ measureTileSize = desiredTileWidth;
+ }
+ } else if (specHeightMode == MeasureSpec.EXACTLY || specHeightMode == MeasureSpec.AT_MOST) {
+ //Be the height size the user wants
+ measureTileSize = desiredTileHeight;
+ }
+
+ if (measureTileSize > 0) {
+ //Use measureTileSize if set
+ measureTileHeight = measureTileSize;
+ measureTileWidth = measureTileSize;
+ } else if (measureTileSize <= 0) {
+ if (measureTileWidth <= 0) {
+ //Set width to default if no value were set
+ measureTileWidth = dpToPx(DEFAULT_TILE_SIZE_DP);
+ }
+ if (measureTileHeight <= 0) {
+ //Set height to default if no value were set
+ measureTileHeight = dpToPx(DEFAULT_TILE_SIZE_DP);
+ }
+ }
+
+ //Calculate our size based off our measured tile size
+ int measuredWidth = measureTileWidth * DEFAULT_DAYS_IN_WEEK;
+ int measuredHeight = measureTileHeight * viewTileHeight;
+
+ //Put padding back in from when we took it away
+ measuredWidth += getPaddingLeft() + getPaddingRight();
+ measuredHeight += getPaddingTop() + getPaddingBottom();
+
+ //Contract fulfilled, setting out measurements
+ setMeasuredDimension(
+ //We clamp inline because we want to use un-clamped versions on the children
+ clampSize(measuredWidth, widthMeasureSpec),
+ clampSize(measuredHeight, heightMeasureSpec)
+ );
+
+ int count = getChildCount();
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+
+ LayoutParams p = (LayoutParams) child.getLayoutParams();
+
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ DEFAULT_DAYS_IN_WEEK * measureTileWidth,
+ MeasureSpec.EXACTLY
+ );
+
+ int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ p.height * measureTileHeight,
+ MeasureSpec.EXACTLY
+ );
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+
+ private int getWeekCountBasedOnMode() {
+ int weekCount = calendarMode.visibleWeeksCount;
+ final boolean isInMonthsMode = calendarMode.equals(CalendarMode.MONTHS);
+ if (isInMonthsMode && mDynamicHeightEnabled && adapter != null && pager != null) {
+ final LocalDate cal = adapter.getItem(pager.getCurrentItem()).getDate();
+ final LocalDate tempLastDay = cal.withDayOfMonth(cal.lengthOfMonth());
+ weekCount = tempLastDay.get(WeekFields.of(firstDayOfWeek, 1).weekOfMonth());
+ }
+ return showWeekDays ? weekCount + DAY_NAMES_ROW : weekCount;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ final int count = getChildCount();
+
+ final int parentLeft = getPaddingLeft();
+ final int parentWidth = right - left - parentLeft - getPaddingRight();
+
+ int childTop = getPaddingTop();
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == View.GONE) {
+ continue;
+ }
+
+ final int width = child.getMeasuredWidth();
+ final int height = child.getMeasuredHeight();
+
+ int delta = (parentWidth - width) / 2;
+ int childLeft = parentLeft + delta;
+
+ child.layout(childLeft, childTop, childLeft + width, childTop + height);
+
+ childTop += height;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(1);
+ }
+
+ @Override
+ public boolean shouldDelayChildPressedState() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(1);
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(MaterialCalendarView.class.getName());
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(MaterialCalendarView.class.getName());
+ }
+
+ /**
+ * @return true if swiping months is enabled, false if disabled. Default is true.
+ */
+ public boolean isPagingEnabled() {
+ return pager.isPagingEnabled();
+ }
+
+ /**
+ * Enable or disable the ability to swipe between months.
+ *
+ * @param pagingEnabled pass false to disable paging, true to enable (default)
+ */
+ public void setPagingEnabled(boolean pagingEnabled) {
+ pager.setPagingEnabled(pagingEnabled);
+ updateUi();
+ }
+
+ /**
+ * Preserve the current parameters of the Material Calendar View.
+ */
+ public State state() {
+ return state;
+ }
+
+ /**
+ * Initialize the parameters from scratch.
+ */
+ public StateBuilder newState() {
+ return new StateBuilder();
+ }
+
+ private void commit(State state) {
+ // Use the calendarDayToShow to determine which date to focus on for the case of switching between month and week views
+ CalendarDay calendarDayToShow = null;
+ if (adapter != null && state.cacheCurrentPosition) {
+ calendarDayToShow = adapter.getItem(pager.getCurrentItem());
+ if (calendarMode != state.calendarMode) {
+ CalendarDay currentlySelectedDate = getSelectedDate();
+ if (calendarMode == CalendarMode.MONTHS && currentlySelectedDate != null) {
+ // Going from months to weeks
+ LocalDate lastVisibleCalendar = calendarDayToShow.getDate();
+ CalendarDay lastVisibleCalendarDay = CalendarDay.from(lastVisibleCalendar.plusDays(1));
+ if (currentlySelectedDate.equals(calendarDayToShow) ||
+ (currentlySelectedDate.isAfter(calendarDayToShow) && currentlySelectedDate.isBefore(
+ lastVisibleCalendarDay))) {
+ // Currently selected date is within view, so center on that
+ calendarDayToShow = currentlySelectedDate;
+ }
+ } else if (calendarMode == CalendarMode.WEEKS) {
+ // Going from weeks to months
+ LocalDate lastVisibleCalendar = calendarDayToShow.getDate();
+ CalendarDay lastVisibleCalendarDay = CalendarDay.from(lastVisibleCalendar.plusDays(6));
+ if (currentlySelectedDate != null &&
+ (currentlySelectedDate.equals(calendarDayToShow) || currentlySelectedDate.equals(
+ lastVisibleCalendarDay) ||
+ (currentlySelectedDate.isAfter(calendarDayToShow)
+ && currentlySelectedDate.isBefore(lastVisibleCalendarDay)))) {
+ // Currently selected date is within view, so center on that
+ calendarDayToShow = currentlySelectedDate;
+ } else {
+ calendarDayToShow = lastVisibleCalendarDay;
+ }
+ }
+ }
+ }
+
+ this.state = state;
+ // Save states parameters
+ calendarMode = state.calendarMode;
+ firstDayOfWeek = state.firstDayOfWeek;
+ minDate = state.minDate;
+ maxDate = state.maxDate;
+ showWeekDays = state.showWeekDays;
+
+ // Recreate adapter
+ final CalendarPagerAdapter> newAdapter;
+ switch (calendarMode) {
+ case MONTHS:
+ newAdapter = new MonthPagerAdapter(this);
+ break;
+ case WEEKS:
+ newAdapter = new WeekPagerAdapter(this);
+ break;
+ default:
+ throw new IllegalArgumentException("Provided display mode which is not yet implemented");
+ }
+ if (adapter == null) {
+ adapter = newAdapter;
+ } else {
+ adapter = adapter.migrateStateAndReturn(newAdapter);
+ }
+ adapter.setShowWeekDays(showWeekDays);
+ pager.setAdapter(adapter);
+ setRangeDates(minDate, maxDate);
+
+ // Reset height params after mode change
+ int tileHeight = showWeekDays ? calendarMode.visibleWeeksCount + DAY_NAMES_ROW
+ : calendarMode.visibleWeeksCount;
+ pager.setLayoutParams(new LayoutParams(tileHeight));
+
+ setCurrentDate(
+ selectionMode == SELECTION_MODE_SINGLE && !adapter.getSelectedDates().isEmpty()
+ ? adapter.getSelectedDates().get(0)
+ : CalendarDay.today());
+
+ if (calendarDayToShow != null) {
+ pager.setCurrentItem(adapter.getIndexForDay(calendarDayToShow));
+ }
+
+ invalidateDecorators();
+ updateUi();
+ }
+
+ /**
+ * {@linkplain IntDef} annotation for selection mode.
+ *
+ * @see #setSelectionMode(int)
+ * @see #getSelectionMode()
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ {SELECTION_MODE_NONE, SELECTION_MODE_SINGLE, SELECTION_MODE_MULTIPLE, SELECTION_MODE_RANGE})
+ public @interface SelectionMode {
+ }
+
+ /**
+ * {@linkplain IntDef} annotation for showOtherDates.
+ *
+ * @see #setShowOtherDates(int)
+ * @see #getShowOtherDates()
+ */
+ @SuppressLint("UniqueConstants")
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = {
+ SHOW_NONE, SHOW_ALL, SHOW_DEFAULTS,
+ SHOW_OUT_OF_RANGE, SHOW_OTHER_MONTHS, SHOW_DECORATED_DISABLED
+ })
+ public @interface ShowOtherDates {
+ }
+
+ public static class SavedState extends BaseSavedState {
+
+ public static final Parcelable.Creator CREATOR
+ = new Parcelable.Creator() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ int showOtherDates = SHOW_DEFAULTS;
+ boolean allowClickDaysOutsideCurrentMonth = true;
+ CalendarDay minDate = null;
+ CalendarDay maxDate = null;
+ List selectedDates = new ArrayList<>();
+ boolean topbarVisible = true;
+ int selectionMode = SELECTION_MODE_SINGLE;
+ boolean dynamicHeightEnabled = false;
+ CalendarDay currentMonth = null;
+ boolean cacheCurrentPosition;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ showOtherDates = in.readInt();
+ allowClickDaysOutsideCurrentMonth = in.readByte() != 0;
+ ClassLoader loader = CalendarDay.class.getClassLoader();
+ minDate = in.readParcelable(loader);
+ maxDate = in.readParcelable(loader);
+ in.readTypedList(selectedDates, CalendarDay.CREATOR);
+ topbarVisible = in.readInt() == 1;
+ selectionMode = in.readInt();
+ dynamicHeightEnabled = in.readInt() == 1;
+ currentMonth = in.readParcelable(loader);
+ cacheCurrentPosition = in.readByte() != 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(showOtherDates);
+ out.writeByte((byte) (allowClickDaysOutsideCurrentMonth ? 1 : 0));
+ out.writeParcelable(minDate, 0);
+ out.writeParcelable(maxDate, 0);
+ out.writeTypedList(selectedDates);
+ out.writeInt(topbarVisible ? 1 : 0);
+ out.writeInt(selectionMode);
+ out.writeInt(dynamicHeightEnabled ? 1 : 0);
+ out.writeParcelable(currentMonth, 0);
+ out.writeByte((byte) (cacheCurrentPosition ? 1 : 0));
+ }
+ }
+
+ /**
+ * Simple layout params for MaterialCalendarView. The only variation for layout is height.
+ */
+ protected static class LayoutParams extends MarginLayoutParams {
+
+ /**
+ * Create a layout that matches parent width, and is X number of tiles high
+ *
+ * @param tileHeight view height in number of tiles
+ */
+ public LayoutParams(int tileHeight) {
+ super(MATCH_PARENT, tileHeight);
+ }
+ }
+
+ public class State {
+ private final CalendarMode calendarMode;
+ private final DayOfWeek firstDayOfWeek;
+ private final CalendarDay minDate;
+ private final CalendarDay maxDate;
+ private final boolean cacheCurrentPosition;
+ private final boolean showWeekDays;
+
+ private State(final StateBuilder builder) {
+ calendarMode = builder.calendarMode;
+ firstDayOfWeek = builder.firstDayOfWeek;
+ minDate = builder.minDate;
+ maxDate = builder.maxDate;
+ cacheCurrentPosition = builder.cacheCurrentPosition;
+ showWeekDays = builder.showWeekDays;
+ }
+
+ /**
+ * Modify parameters from current state.
+ */
+ public StateBuilder edit() {
+ return new StateBuilder(this);
+ }
+ }
+
+ public class StateBuilder {
+ private CalendarMode calendarMode;
+ private DayOfWeek firstDayOfWeek;
+ private boolean cacheCurrentPosition = false;
+ private CalendarDay minDate = null;
+ private CalendarDay maxDate = null;
+ private boolean showWeekDays;
+
+ public StateBuilder() {
+ calendarMode = CalendarMode.MONTHS;
+ firstDayOfWeek =
+ LocalDate.now().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 1).getDayOfWeek();
+ }
+
+ private StateBuilder(final State state) {
+ calendarMode = state.calendarMode;
+ firstDayOfWeek = state.firstDayOfWeek;
+ minDate = state.minDate;
+ maxDate = state.maxDate;
+ cacheCurrentPosition = state.cacheCurrentPosition;
+ showWeekDays = state.showWeekDays;
+ }
+
+ /**
+ * Sets the first day of the week.
+ *
+ * Uses the {@link DayOfWeek} day constants.
+ *
+ * @param day The first day of the week as a {@link DayOfWeek} enum.
+ * @see java.util.Calendar
+ */
+ public StateBuilder setFirstDayOfWeek(DayOfWeek day) {
+ this.firstDayOfWeek = day;
+ return this;
+ }
+
+ /**
+ * Set calendar display mode. The default mode is Months.
+ * When switching between modes will select todays date, or the selected date,
+ * if selection mode is single.
+ *
+ * @param mode - calendar mode
+ */
+ public StateBuilder setCalendarDisplayMode(CalendarMode mode) {
+ this.calendarMode = mode;
+ return this;
+ }
+
+ /**
+ * @param date set the minimum selectable date, null for no minimum
+ */
+ public StateBuilder setMinimumDate(@Nullable LocalDate date) {
+ setMinimumDate(CalendarDay.from(date));
+ return this;
+ }
+
+ /**
+ * @param calendar set the minimum selectable date, null for no minimum
+ */
+ public StateBuilder setMinimumDate(@Nullable CalendarDay calendar) {
+ minDate = calendar;
+ return this;
+ }
+
+ /**
+ * @param date set the maximum selectable date, null for no maximum
+ */
+ public StateBuilder setMaximumDate(@Nullable LocalDate date) {
+ setMaximumDate(CalendarDay.from(date));
+ return this;
+ }
+
+ /**
+ * @param calendar set the maximum selectable date, null for no maximum
+ */
+ public StateBuilder setMaximumDate(@Nullable CalendarDay calendar) {
+ maxDate = calendar;
+ return this;
+ }
+
+ /**
+ * @param showWeekDays true to show week days names
+ */
+ public StateBuilder setShowWeekDays(boolean showWeekDays) {
+ this.showWeekDays = showWeekDays;
+ return this;
+ }
+
+ /**
+ * Use this method to enable saving the current position when switching
+ * between week and month mode. By default, the calendar update to the latest selected date
+ * or the current date. When set to true, the view will used the month that the calendar is
+ * currently on.
+ *
+ * @param cacheCurrentPosition Set to true to cache the current position, false otherwise.
+ */
+ public StateBuilder isCacheCalendarPositionEnabled(final boolean cacheCurrentPosition) {
+ this.cacheCurrentPosition = cacheCurrentPosition;
+ return this;
+ }
+
+ public void commit() {
+ MaterialCalendarView.this.commit(new State(this));
+ }
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarViewInitProvider.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarViewInitProvider.java
index cc7f2d4a..3516cb79 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarViewInitProvider.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarViewInitProvider.java
@@ -6,8 +6,9 @@
import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.jakewharton.threetenabp.AndroidThreeTen;
/**
@@ -15,61 +16,72 @@
*/
public final class MaterialCalendarViewInitProvider extends ContentProvider {
- private static final String MCV_AUTHORITY =
- "com.prolificinteractive.materialcalendarview.materialcalendarviewinitprovider";
-
- public MaterialCalendarViewInitProvider() { }
+ private static final String MCV_AUTHORITY =
+ "com.prolificinteractive.materialcalendarview.materialcalendarviewinitprovider";
- @Override public boolean onCreate() {
- // The interesting piece here.
- AndroidThreeTen.init(getContext());
- return true;
- }
+ public MaterialCalendarViewInitProvider() {
+ }
- @Override public void attachInfo(final Context context, final ProviderInfo providerInfo) {
- if (providerInfo == null) {
- throw new NullPointerException("MaterialCalendarViewInitProvider ProviderInfo cannot be null.");
+ @Override
+ public boolean onCreate() {
+ // The interesting piece here.
+ AndroidThreeTen.init(getContext());
+ return true;
}
- // So if the authorities equal the library internal ones, the developer forgot to set his applicationId
- if (MCV_AUTHORITY.equals(providerInfo.authority)) {
- throw new IllegalStateException(
- "Incorrect provider authority in manifest. Most likely due to a "
- + "missing applicationId variable in application\'s build.gradle.");
+
+ @Override
+ public void attachInfo(final Context context, final ProviderInfo providerInfo) {
+ if (providerInfo == null) {
+ throw new NullPointerException("MaterialCalendarViewInitProvider ProviderInfo cannot be null.");
+ }
+ // So if the authorities equal the library internal ones, the developer forgot to set his applicationId
+ if (MCV_AUTHORITY.equals(providerInfo.authority)) {
+ throw new IllegalStateException(
+ "Incorrect provider authority in manifest. Most likely due to a "
+ + "missing applicationId variable in application\'s build.gradle.");
+ }
+ super.attachInfo(context, providerInfo);
}
- super.attachInfo(context, providerInfo);
- }
- @Nullable @Override public Cursor query(
- @NonNull final Uri uri,
- @Nullable final String[] projection,
- @Nullable final String selection,
- @Nullable final String[] selectionArgs,
- @Nullable final String sortOrder) {
- return null;
- }
+ @Nullable
+ @Override
+ public Cursor query(
+ @NonNull final Uri uri,
+ @Nullable final String[] projection,
+ @Nullable final String selection,
+ @Nullable final String[] selectionArgs,
+ @Nullable final String sortOrder) {
+ return null;
+ }
- @Nullable @Override public String getType(@NonNull final Uri uri) {
- return null;
- }
+ @Nullable
+ @Override
+ public String getType(@NonNull final Uri uri) {
+ return null;
+ }
- @Nullable @Override public Uri insert(
- @NonNull final Uri uri,
- @Nullable final ContentValues values) {
- return null;
- }
+ @Nullable
+ @Override
+ public Uri insert(
+ @NonNull final Uri uri,
+ @Nullable final ContentValues values) {
+ return null;
+ }
- @Override public int delete(
- @NonNull final Uri uri,
- @Nullable final String selection,
- @Nullable final String[] selectionArgs) {
- return 0;
- }
+ @Override
+ public int delete(
+ @NonNull final Uri uri,
+ @Nullable final String selection,
+ @Nullable final String[] selectionArgs) {
+ return 0;
+ }
- @Override public int update(
- @NonNull final Uri uri,
- @Nullable final ContentValues values,
- @Nullable final String selection,
- @Nullable final String[] selectionArgs) {
- return 0;
- }
+ @Override
+ public int update(
+ @NonNull final Uri uri,
+ @Nullable final ContentValues values,
+ @Nullable final String selection,
+ @Nullable final String[] selectionArgs) {
+ return 0;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthPagerAdapter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthPagerAdapter.java
index 1e205310..b557cfdf 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthPagerAdapter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthPagerAdapter.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import org.threeten.bp.Period;
/**
@@ -8,56 +9,63 @@
*/
class MonthPagerAdapter extends CalendarPagerAdapter {
- MonthPagerAdapter(MaterialCalendarView mcv) {
- super(mcv);
- }
+ MonthPagerAdapter(MaterialCalendarView mcv) {
+ super(mcv);
+ }
- @Override protected MonthView createView(int position) {
- return new MonthView(mcv, getItem(position), mcv.getFirstDayOfWeek(), showWeekDays);
- }
+ @Override
+ protected MonthView createView(int position) {
+ return new MonthView(mcv, getItem(position), mcv.getFirstDayOfWeek(), showWeekDays);
+ }
- @Override protected int indexOf(MonthView view) {
- CalendarDay month = view.getMonth();
- return getRangeIndex().indexOf(month);
- }
+ @Override
+ protected int indexOf(MonthView view) {
+ CalendarDay month = view.getMonth();
+ return getRangeIndex().indexOf(month);
+ }
- @Override protected boolean isInstanceOfView(Object object) {
- return object instanceof MonthView;
- }
+ @Override
+ protected boolean isInstanceOfView(Object object) {
+ return object instanceof MonthView;
+ }
- @Override protected DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max) {
- return new Monthly(min, max);
- }
+ @Override
+ protected DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max) {
+ return new Monthly(min, max);
+ }
- public static class Monthly implements DateRangeIndex {
+ public static class Monthly implements DateRangeIndex {
- /**
- * Minimum date with the first month to display.
- */
- private final CalendarDay min;
+ /**
+ * Minimum date with the first month to display.
+ */
+ private final CalendarDay min;
- /**
- * Number of months to display.
- */
- private final int count;
+ /**
+ * Number of months to display.
+ */
+ private final int count;
- public Monthly(@NonNull final CalendarDay min, @NonNull final CalendarDay max) {
- this.min = CalendarDay.from(min.getYear(), min.getMonth(), 1);
- this.count = indexOf(max) + 1;
- }
+ public Monthly(@NonNull final CalendarDay min, @NonNull final CalendarDay max) {
+ this.min = CalendarDay.from(min.getYear(), min.getMonth(), 1);
+ this.count = indexOf(max) + 1;
+ }
- @Override public int getCount() {
- return count;
- }
+ @Override
+ public int getCount() {
+ return count;
+ }
- @Override public int indexOf(final CalendarDay day) {
- return (int) Period
- .between(min.getDate().withDayOfMonth(1), day.getDate().withDayOfMonth(1))
- .toTotalMonths();
- }
+ @Override
+ public int indexOf(final CalendarDay day) {
+ return (int) Period
+ .between(min.getDate().withDayOfMonth(1), day.getDate().withDayOfMonth(1))
+ .toTotalMonths();
+ }
- @Override public CalendarDay getItem(final int position) {
- return CalendarDay.from(min.getDate().plusMonths(position));
+ @Override
+ public CalendarDay getItem(final int position) {
+ return CalendarDay.from(min.getDate().plusMonths(position));
+ }
}
- }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthView.java
index 1fae0818..0ab195f4 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MonthView.java
@@ -1,46 +1,52 @@
package com.prolificinteractive.materialcalendarview;
import android.annotation.SuppressLint;
-import android.support.annotation.NonNull;
-import java.util.Collection;
+import androidx.annotation.NonNull;
+
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
+import java.util.Collection;
+
/**
* Display a month of {@linkplain DayView}s and
* seven {@linkplain WeekDayView}s.
*/
-@SuppressLint("ViewConstructor") class MonthView extends CalendarPagerView {
-
- public MonthView(
- @NonNull final MaterialCalendarView view,
- final CalendarDay month,
- final DayOfWeek firstDayOfWeek,
- final boolean showWeekDays) {
- super(view, month, firstDayOfWeek, showWeekDays);
- }
-
- @Override protected void buildDayViews(
- final Collection dayViews,
- final LocalDate calendar) {
- LocalDate temp = calendar;
- for (int r = 0; r < DEFAULT_MAX_WEEKS; r++) {
- for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
- addDayView(dayViews, temp);
- temp = temp.plusDays(1);
- }
+@SuppressLint("ViewConstructor")
+class MonthView extends CalendarPagerView {
+
+ public MonthView(
+ @NonNull final MaterialCalendarView view,
+ final CalendarDay month,
+ final DayOfWeek firstDayOfWeek,
+ final boolean showWeekDays) {
+ super(view, month, firstDayOfWeek, showWeekDays);
}
- }
- public CalendarDay getMonth() {
- return getFirstViewDay();
- }
+ @Override
+ protected void buildDayViews(
+ final Collection dayViews,
+ final LocalDate calendar) {
+ LocalDate temp = calendar;
+ for (int r = 0; r < DEFAULT_MAX_WEEKS; r++) {
+ for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
+ addDayView(dayViews, temp);
+ temp = temp.plusDays(1);
+ }
+ }
+ }
- @Override protected boolean isDayEnabled(final CalendarDay day) {
- return day.getMonth() == getFirstViewDay().getMonth();
- }
+ public CalendarDay getMonth() {
+ return getFirstViewDay();
+ }
- @Override protected int getRows() {
- return showWeekDays ? DEFAULT_MAX_WEEKS + DAY_NAMES_ROW : DEFAULT_MAX_WEEKS;
- }
+ @Override
+ protected boolean isDayEnabled(final CalendarDay day) {
+ return day.getMonth() == getFirstViewDay().getMonth();
+ }
+
+ @Override
+ protected int getRows() {
+ return showWeekDays ? DEFAULT_MAX_WEEKS + DAY_NAMES_ROW : DEFAULT_MAX_WEEKS;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MySelectorDecorator.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MySelectorDecorator.java
new file mode 100644
index 00000000..1c6510de
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MySelectorDecorator.java
@@ -0,0 +1,41 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.text.style.ForegroundColorSpan;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+public class MySelectorDecorator implements DayViewDecorator {
+
+ private final Drawable drawable;
+ private HashSet dates;
+
+
+ public MySelectorDecorator(Activity context, Collection dates, int Drawable) {
+ drawable = context.getResources().getDrawable(Drawable);
+ this.dates = new HashSet<>(dates);
+ }
+
+ public MySelectorDecorator(Activity context, int Drawable) {
+ drawable = context.getResources().getDrawable(Drawable);
+ }
+
+ @Override
+ public boolean shouldDecorate(CalendarDay day) {
+ return dates == null || dates.contains(day);
+ }
+
+ @Override
+ public void decorate(DayViewFacade view) {
+ view.setSelectionDrawable(drawable);
+ if (dates != null) {
+ view.addSpan(new ForegroundColorSpan(Color.WHITE));
+ }
+ }
+}
+
+
+
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/NoSelectionDecorator.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/NoSelectionDecorator.java
new file mode 100644
index 00000000..18ee0679
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/NoSelectionDecorator.java
@@ -0,0 +1,21 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.graphics.Color;
+import android.text.style.ForegroundColorSpan;
+
+public class NoSelectionDecorator implements DayViewDecorator {
+
+ public NoSelectionDecorator() {
+ }
+
+ @Override
+ public boolean shouldDecorate(CalendarDay day) {
+ return true;
+ }
+
+ @Override
+ public void decorate(DayViewFacade view) {
+ view.addSpan(new ForegroundColorSpan(Color.BLACK));
+
+ }
+}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateLongClickListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateLongClickListener.java
index e1fbc208..61201b81 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateLongClickListener.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateLongClickListener.java
@@ -1,18 +1,18 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
/**
* The callback used to indicate a date has been long clicked.
*/
public interface OnDateLongClickListener {
- /**
- * Called when a user long clicks on a day.
- * There is no logic to prevent multiple calls for the same date and state.
- *
- * @param widget the view associated with this listener
- * @param date the date that was long clicked.
- */
- void onDateLongClick(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date);
+ /**
+ * Called when a user long clicks on a day.
+ * There is no logic to prevent multiple calls for the same date and state.
+ *
+ * @param widget the view associated with this listener
+ * @param date the date that was long clicked.
+ */
+ void onDateLongClick(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateSelectedListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateSelectedListener.java
index e4ea640c..f2dba380 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateSelectedListener.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnDateSelectedListener.java
@@ -1,22 +1,22 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
/**
* The callback used to indicate a date has been selected or deselected
*/
public interface OnDateSelectedListener {
- /**
- * Called when a user clicks on a day.
- * There is no logic to prevent multiple calls for the same date and state.
- *
- * @param widget the view associated with this listener
- * @param date the date that was selected or unselected
- * @param selected true if the day is now selected, false otherwise
- */
- void onDateSelected(
- @NonNull MaterialCalendarView widget,
- @NonNull CalendarDay date,
- boolean selected);
+ /**
+ * Called when a user clicks on a day.
+ * There is no logic to prevent multiple calls for the same date and state.
+ *
+ * @param widget the view associated with this listener
+ * @param date the date that was selected or unselected
+ * @param selected true if the day is now selected, false otherwise
+ */
+ void onDateSelected(
+ @NonNull MaterialCalendarView widget,
+ @NonNull CalendarDay date,
+ boolean selected);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnMonthChangedListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnMonthChangedListener.java
index 16f4b576..8b20de65 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnMonthChangedListener.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnMonthChangedListener.java
@@ -5,11 +5,11 @@
*/
public interface OnMonthChangedListener {
- /**
- * Called upon change of the selected day
- *
- * @param widget the view associated with this listener
- * @param date the month picked, as the first day of the month
- */
- void onMonthChanged(MaterialCalendarView widget, CalendarDay date);
+ /**
+ * Called upon change of the selected day
+ *
+ * @param widget the view associated with this listener
+ * @param date the month picked, as the first day of the month
+ */
+ void onMonthChanged(MaterialCalendarView widget, CalendarDay date);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java
index 97c41715..3982c78a 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import java.util.List;
/**
@@ -8,12 +9,12 @@
*/
public interface OnRangeSelectedListener {
- /**
- * Called when a user selects a range of days.
- * There is no logic to prevent multiple calls for the same date and state.
- *
- * @param widget the view associated with this listener
- * @param dates the dates in the range, in ascending order
- */
- void onRangeSelected(@NonNull MaterialCalendarView widget, @NonNull List dates);
+ /**
+ * Called when a user selects a range of days.
+ * There is no logic to prevent multiple calls for the same date and state.
+ *
+ * @param widget the view associated with this listener
+ * @param dates the dates in the range, in ascending order
+ */
+ void onRangeSelected(@NonNull MaterialCalendarView widget, @NonNull List dates);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/RtlViewPager.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/RtlViewPager.java
new file mode 100644
index 00000000..02f1dc7e
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/RtlViewPager.java
@@ -0,0 +1,422 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.core.view.ViewCompat;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import java.util.HashMap;
+
+public class RtlViewPager extends ViewPager {
+
+ private final HashMap mPageChangeListeners = new HashMap<>();
+ private int mLayoutDirection = ViewCompat.LAYOUT_DIRECTION_LTR;
+
+ public RtlViewPager(Context context) {
+ super(context);
+ }
+
+ public RtlViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void onRtlPropertiesChanged(int layoutDirection) {
+ super.onRtlPropertiesChanged(layoutDirection);
+ int viewCompatLayoutDirection = layoutDirection == View.LAYOUT_DIRECTION_RTL ? ViewCompat.LAYOUT_DIRECTION_RTL : ViewCompat.LAYOUT_DIRECTION_LTR;
+ if (viewCompatLayoutDirection != mLayoutDirection) {
+ PagerAdapter adapter = super.getAdapter();
+ int position = 0;
+ if (adapter != null) {
+ position = getCurrentItem();
+ }
+ mLayoutDirection = viewCompatLayoutDirection;
+ if (adapter != null) {
+ adapter.notifyDataSetChanged();
+ setCurrentItem(position);
+ }
+ }
+ }
+
+ @Override
+ public PagerAdapter getAdapter() {
+ ReversingAdapter adapter = (ReversingAdapter) super.getAdapter();
+ return adapter == null ? null : adapter.getDelegate();
+ }
+
+ @Override
+ public void setAdapter(PagerAdapter adapter) {
+ if (adapter != null) {
+ adapter = new ReversingAdapter(adapter);
+ }
+ super.setAdapter(adapter);
+ setCurrentItem(0);
+ }
+
+ private boolean isRtl() {
+ return mLayoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
+ }
+
+ @Override
+ public int getCurrentItem() {
+ int item = super.getCurrentItem();
+ PagerAdapter adapter = super.getAdapter();
+ if (adapter != null && isRtl()) {
+ item = adapter.getCount() - item - 1;
+ }
+ return item;
+ }
+
+ @Override
+ public void setCurrentItem(int position) {
+ PagerAdapter adapter = super.getAdapter();
+ if (adapter != null && isRtl()) {
+ position = adapter.getCount() - position - 1;
+ }
+ super.setCurrentItem(position);
+ }
+
+ @Override
+ public void setCurrentItem(int position, boolean smoothScroll) {
+ PagerAdapter adapter = super.getAdapter();
+ if (adapter != null && isRtl()) {
+ position = adapter.getCount() - position - 1;
+ }
+ super.setCurrentItem(position, smoothScroll);
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ return new SavedState(superState, mLayoutDirection);
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState ss = (SavedState) state;
+ mLayoutDirection = ss.mLayoutDirection;
+ super.onRestoreInstanceState(ss.mViewPagerSavedState);
+ }
+
+ @Override
+ public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
+ ReversingOnPageChangeListener reversingListener = new ReversingOnPageChangeListener(listener);
+ mPageChangeListeners.put(listener, reversingListener);
+ super.addOnPageChangeListener(reversingListener);
+ }
+
+ @Override
+ public void removeOnPageChangeListener(@NonNull OnPageChangeListener listener) {
+ ReversingOnPageChangeListener reverseListener = mPageChangeListeners.remove(listener);
+ if (reverseListener != null) {
+ super.removeOnPageChangeListener(reverseListener);
+ }
+ }
+
+ @Override
+ public void clearOnPageChangeListeners() {
+ super.clearOnPageChangeListeners();
+ mPageChangeListeners.clear();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
+ int height = 0;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ int h = child.getMeasuredHeight();
+ if (h > height) {
+ height = h;
+ }
+ }
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ public static class SavedState implements Parcelable {
+
+ // The `CREATOR` field is used to create the parcelable from a parcel, even though it is never referenced directly.
+ public static final Parcelable.ClassLoaderCreator CREATOR
+ = new Parcelable.ClassLoaderCreator() {
+
+ @Override
+ public SavedState createFromParcel(Parcel source) {
+ return createFromParcel(source, null);
+ }
+
+ @Override
+ public SavedState createFromParcel(Parcel source, ClassLoader loader) {
+ return new SavedState(source, loader);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ private final Parcelable mViewPagerSavedState;
+ private final int mLayoutDirection;
+
+ private SavedState(Parcelable viewPagerSavedState, int layoutDirection) {
+ mViewPagerSavedState = viewPagerSavedState;
+ mLayoutDirection = layoutDirection;
+ }
+
+ private SavedState(Parcel in, ClassLoader loader) {
+ if (loader == null) {
+ loader = getClass().getClassLoader();
+ }
+ mViewPagerSavedState = in.readParcelable(loader);
+ mLayoutDirection = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(mViewPagerSavedState, flags);
+ out.writeInt(mLayoutDirection);
+ }
+ }
+
+ public static class DelegatingPagerAdapter extends PagerAdapter {
+
+ private final PagerAdapter mDelegate;
+
+ DelegatingPagerAdapter(@NonNull final PagerAdapter delegate) {
+ this.mDelegate = delegate;
+ delegate.registerDataSetObserver(new MyDataSetObserver(this));
+ }
+
+ PagerAdapter getDelegate() {
+ return mDelegate;
+ }
+
+ @Override
+ public int getCount() {
+ return mDelegate.getCount();
+ }
+
+ @Override
+ public void startUpdate(@NonNull ViewGroup container) {
+ mDelegate.startUpdate(container);
+ }
+
+ @Override
+ public @NonNull
+ Object instantiateItem(@NonNull ViewGroup container, int position) {
+ return mDelegate.instantiateItem(container, position);
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ mDelegate.destroyItem(container, position, object);
+ }
+
+ @Override
+ public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ mDelegate.setPrimaryItem(container, position, object);
+ }
+
+ @Override
+ public void finishUpdate(@NonNull ViewGroup container) {
+ mDelegate.finishUpdate(container);
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return mDelegate.isViewFromObject(view, object);
+ }
+
+ @Override
+ public Parcelable saveState() {
+ return mDelegate.saveState();
+ }
+
+ @Override
+ public void restoreState(Parcelable state, ClassLoader loader) {
+ mDelegate.restoreState(state, loader);
+ }
+
+ @Override
+ public int getItemPosition(@NonNull Object object) {
+ return mDelegate.getItemPosition(object);
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ mDelegate.notifyDataSetChanged();
+ }
+
+ @Override
+ public void registerDataSetObserver(@NonNull DataSetObserver observer) {
+ mDelegate.registerDataSetObserver(observer);
+ }
+
+ @Override
+ public void unregisterDataSetObserver(@NonNull DataSetObserver observer) {
+ mDelegate.unregisterDataSetObserver(observer);
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return mDelegate.getPageTitle(position);
+ }
+
+ @Override
+ public float getPageWidth(int position) {
+ return mDelegate.getPageWidth(position);
+ }
+
+ private void superNotifyDataSetChanged() {
+ super.notifyDataSetChanged();
+ }
+
+ private static class MyDataSetObserver extends DataSetObserver {
+
+ final DelegatingPagerAdapter mParent;
+
+ private MyDataSetObserver(DelegatingPagerAdapter mParent) {
+ this.mParent = mParent;
+ }
+
+ @Override
+ public void onChanged() {
+ if (mParent != null) {
+ mParent.superNotifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onInvalidated() {
+ onChanged();
+ }
+ }
+ }
+
+ private class ReversingOnPageChangeListener implements OnPageChangeListener {
+
+ private final OnPageChangeListener mListener;
+
+ ReversingOnPageChangeListener(OnPageChangeListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ // The documentation says that `getPageWidth(...)` returns the fraction of the _measured_ width that that page takes up. However, the code seems to
+ // use the width so we will here too.
+ final int width = getWidth();
+ PagerAdapter adapter = RtlViewPager.super.getAdapter();
+ if (isRtl() && adapter != null) {
+ int count = adapter.getCount();
+ int remainingWidth = (int) (width * (1 - adapter.getPageWidth(position))) + positionOffsetPixels;
+ while (position < count && remainingWidth > 0) {
+ position += 1;
+ remainingWidth -= (int) (width * adapter.getPageWidth(position));
+ }
+ position = count - position - 1;
+ positionOffsetPixels = -remainingWidth;
+ positionOffset = positionOffsetPixels / (width * adapter.getPageWidth(position));
+ }
+ mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ PagerAdapter adapter = RtlViewPager.super.getAdapter();
+ if (isRtl() && adapter != null) {
+ position = adapter.getCount() - position - 1;
+ }
+ mListener.onPageSelected(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ mListener.onPageScrollStateChanged(state);
+ }
+ }
+
+ private class ReversingAdapter extends DelegatingPagerAdapter {
+
+ ReversingAdapter(@NonNull PagerAdapter adapter) {
+ super(adapter);
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ if (isRtl()) {
+ position = getCount() - position - 1;
+ }
+ super.destroyItem(container, position, object);
+ }
+
+ @Override
+ public int getItemPosition(@NonNull Object object) {
+ int position = super.getItemPosition(object);
+ if (isRtl()) {
+ if (position == POSITION_UNCHANGED || position == POSITION_NONE) {
+ // We can't accept POSITION_UNCHANGED when in RTL mode because adding items to the end of the collection adds them to the beginning of the
+ // ViewPager. Items whose positions do not change from the perspective of the wrapped adapter actually do change from the perspective of
+ // the ViewPager.
+ position = POSITION_NONE;
+ } else {
+ position = getCount() - position - 1;
+ }
+ }
+ return position;
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ if (isRtl()) {
+ position = getCount() - position - 1;
+ }
+ return super.getPageTitle(position);
+ }
+
+ @Override
+ public float getPageWidth(int position) {
+ if (isRtl()) {
+ position = getCount() - position - 1;
+ }
+ return super.getPageWidth(position);
+ }
+
+ @Override
+ public @NonNull
+ Object instantiateItem(@NonNull ViewGroup container, int position) {
+ if (isRtl()) {
+ position = getCount() - position - 1;
+ }
+ return super.instantiateItem(container, position);
+ }
+
+ @Override
+ public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ if (isRtl()) {
+ position = getCount() - position - 1;
+ }
+ super.setPrimaryItem(container, position, object);
+ }
+ }
+}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/TitleChanger.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/TitleChanger.java
index 31cef265..0b29cda2 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/TitleChanger.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/TitleChanger.java
@@ -2,148 +2,148 @@
import android.animation.Animator;
import android.content.res.Resources;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.ViewPropertyAnimator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
+
import com.prolificinteractive.materialcalendarview.format.TitleFormatter;
class TitleChanger {
- public static final int DEFAULT_ANIMATION_DELAY = 400;
- public static final int DEFAULT_Y_TRANSLATION_DP = 20;
-
- private final TextView title;
- @NonNull private TitleFormatter titleFormatter = TitleFormatter.DEFAULT;
-
- private final int animDelay;
- private final int animDuration;
- private final int translate;
- private final Interpolator interpolator = new DecelerateInterpolator(2f);
-
- private int orientation = MaterialCalendarView.VERTICAL;
+ public static final int DEFAULT_ANIMATION_DELAY = 400;
+ public static final int DEFAULT_Y_TRANSLATION_DP = 20;
- private long lastAnimTime = 0;
- private CalendarDay previousMonth = null;
+ private final TextView title;
+ private final int animDelay;
+ private final int animDuration;
+ private final int translate;
+ private final Interpolator interpolator = new DecelerateInterpolator(2f);
+ @NonNull
+ private TitleFormatter titleFormatter = TitleFormatter.DEFAULT;
+ private int orientation = MaterialCalendarView.VERTICAL;
- public TitleChanger(TextView title) {
- this.title = title;
+ private long lastAnimTime = 0;
+ private CalendarDay previousMonth = null;
- Resources res = title.getResources();
+ public TitleChanger(TextView title) {
+ this.title = title;
- animDelay = DEFAULT_ANIMATION_DELAY;
+ Resources res = title.getResources();
- animDuration = res.getInteger(android.R.integer.config_shortAnimTime) / 2;
+ animDelay = DEFAULT_ANIMATION_DELAY;
- translate = (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, DEFAULT_Y_TRANSLATION_DP, res.getDisplayMetrics()
- );
- }
+ animDuration = res.getInteger(android.R.integer.config_shortAnimTime) / 2;
- public void change(final CalendarDay currentMonth) {
- long currentTime = System.currentTimeMillis();
-
- if (currentMonth == null) {
- return;
+ translate = (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, DEFAULT_Y_TRANSLATION_DP, res.getDisplayMetrics()
+ );
}
- if (TextUtils.isEmpty(title.getText()) || (currentTime - lastAnimTime) < animDelay) {
- doChange(currentTime, currentMonth, false);
- }
+ public void change(final CalendarDay currentMonth) {
+ long currentTime = System.currentTimeMillis();
- if (currentMonth.equals(previousMonth) ||
- (currentMonth.getMonth() == previousMonth.getMonth()
- && currentMonth.getYear() == previousMonth.getYear())) {
- return;
- }
+ if (currentMonth == null) {
+ return;
+ }
- doChange(currentTime, currentMonth, true);
- }
+ if (TextUtils.isEmpty(title.getText()) || (currentTime - lastAnimTime) < animDelay) {
+ doChange(currentTime, currentMonth, false);
+ }
- private void doChange(final long now, final CalendarDay currentMonth, boolean animate) {
+ if (currentMonth.equals(previousMonth) ||
+ (currentMonth.getMonth() == previousMonth.getMonth()
+ && currentMonth.getYear() == previousMonth.getYear())) {
+ return;
+ }
- title.animate().cancel();
- doTranslation(title, 0);
+ doChange(currentTime, currentMonth, true);
+ }
- title.setAlpha(1);
- lastAnimTime = now;
+ private void doChange(final long now, final CalendarDay currentMonth, boolean animate) {
- final CharSequence newTitle = titleFormatter.format(currentMonth);
+ title.animate().cancel();
+ doTranslation(title, 0);
- if (!animate) {
- title.setText(newTitle);
- } else {
- final int translation = translate * (previousMonth.isBefore(currentMonth) ? 1 : -1);
- final ViewPropertyAnimator viewPropertyAnimator = title.animate();
+ title.setAlpha(1);
+ lastAnimTime = now;
- if (orientation == MaterialCalendarView.HORIZONTAL) {
- viewPropertyAnimator.translationX(translation * -1);
- } else {
- viewPropertyAnimator.translationY(translation * -1);
- }
+ final CharSequence newTitle = titleFormatter.format(currentMonth);
- viewPropertyAnimator
- .alpha(0)
- .setDuration(animDuration)
- .setInterpolator(interpolator)
- .setListener(new AnimatorListener() {
+ if (!animate) {
+ title.setText(newTitle);
+ } else {
+ final int translation = translate * (previousMonth.isBefore(currentMonth) ? 1 : -1);
+ final ViewPropertyAnimator viewPropertyAnimator = title.animate();
- @Override
- public void onAnimationCancel(Animator animator) {
- doTranslation(title, 0);
- title.setAlpha(1);
+ if (orientation == MaterialCalendarView.HORIZONTAL) {
+ viewPropertyAnimator.translationX(translation * -1);
+ } else {
+ viewPropertyAnimator.translationY(translation * -1);
}
- @Override
- public void onAnimationEnd(Animator animator) {
- title.setText(newTitle);
- doTranslation(title, translation);
-
- final ViewPropertyAnimator viewPropertyAnimator = title.animate();
- if (orientation == MaterialCalendarView.HORIZONTAL) {
- viewPropertyAnimator.translationX(0);
- } else {
- viewPropertyAnimator.translationY(0);
- }
-
- viewPropertyAnimator
- .alpha(1)
- .setDuration(animDuration)
- .setInterpolator(interpolator)
- .setListener(new AnimatorListener())
- .start();
- }
- }).start();
+ viewPropertyAnimator
+ .alpha(0)
+ .setDuration(animDuration)
+ .setInterpolator(interpolator)
+ .setListener(new AnimatorListener() {
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ doTranslation(title, 0);
+ title.setAlpha(1);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ title.setText(newTitle);
+ doTranslation(title, translation);
+
+ final ViewPropertyAnimator viewPropertyAnimator = title.animate();
+ if (orientation == MaterialCalendarView.HORIZONTAL) {
+ viewPropertyAnimator.translationX(0);
+ } else {
+ viewPropertyAnimator.translationY(0);
+ }
+
+ viewPropertyAnimator
+ .alpha(1)
+ .setDuration(animDuration)
+ .setInterpolator(interpolator)
+ .setListener(new AnimatorListener())
+ .start();
+ }
+ }).start();
+ }
+
+ previousMonth = currentMonth;
}
- previousMonth = currentMonth;
- }
-
- private void doTranslation(final TextView title, final int translate) {
- if (orientation == MaterialCalendarView.HORIZONTAL) {
- title.setTranslationX(translate);
- } else {
- title.setTranslationY(translate);
+ private void doTranslation(final TextView title, final int translate) {
+ if (orientation == MaterialCalendarView.HORIZONTAL) {
+ title.setTranslationX(translate);
+ } else {
+ title.setTranslationY(translate);
+ }
}
- }
- public void setTitleFormatter(@Nullable final TitleFormatter titleFormatter) {
- this.titleFormatter = titleFormatter == null ? TitleFormatter.DEFAULT : titleFormatter;
- }
+ public void setTitleFormatter(@Nullable final TitleFormatter titleFormatter) {
+ this.titleFormatter = titleFormatter == null ? TitleFormatter.DEFAULT : titleFormatter;
+ }
- public void setOrientation(int orientation) {
- this.orientation = orientation;
- }
+ public int getOrientation() {
+ return orientation;
+ }
- public int getOrientation() {
- return orientation;
- }
+ public void setOrientation(int orientation) {
+ this.orientation = orientation;
+ }
- public void setPreviousMonth(CalendarDay previousMonth) {
- this.previousMonth = previousMonth;
- }
+ public void setPreviousMonth(CalendarDay previousMonth) {
+ this.previousMonth = previousMonth;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/ViolationsDecorator.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/ViolationsDecorator.java
new file mode 100644
index 00000000..ab3ba239
--- /dev/null
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/ViolationsDecorator.java
@@ -0,0 +1,29 @@
+package com.prolificinteractive.materialcalendarview;
+
+import android.app.Activity;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+public class ViolationsDecorator implements DayViewDecorator {
+
+ private int[] color;
+ private HashSet dates;
+ private Activity context;
+
+ public ViolationsDecorator(Activity context, int[] color, Collection dates) {
+ this.color = color;
+ this.dates = new HashSet<>(dates);
+ this.context = context;
+ }
+
+ @Override
+ public boolean shouldDecorate(CalendarDay day) {
+ return dates.contains(day);
+ }
+
+ @Override
+ public void decorate(DayViewFacade view) {
+ view.addSpan(new CustomMultipleDotSpan(context, 6, color));
+ }
+}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekDayView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekDayView.java
index 9d635b52..e2df64a2 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekDayView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekDayView.java
@@ -3,39 +3,42 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.AppCompatTextView;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatTextView;
import android.view.Gravity;
+
import com.prolificinteractive.materialcalendarview.format.WeekDayFormatter;
+
import org.threeten.bp.DayOfWeek;
/**
* Display a day of the week
*/
-@SuppressLint("ViewConstructor") class WeekDayView extends AppCompatTextView {
+@SuppressLint("ViewConstructor")
+class WeekDayView extends AppCompatTextView {
- private WeekDayFormatter formatter = WeekDayFormatter.DEFAULT;
- private DayOfWeek dayOfWeek;
+ private WeekDayFormatter formatter = WeekDayFormatter.DEFAULT;
+ private DayOfWeek dayOfWeek;
- public WeekDayView(final Context context, final DayOfWeek dayOfWeek) {
- super(context);
+ public WeekDayView(final Context context, final DayOfWeek dayOfWeek) {
+ super(context);
- setGravity(Gravity.CENTER);
+ setGravity(Gravity.CENTER);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- setTextAlignment(TEXT_ALIGNMENT_CENTER);
- }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ setTextAlignment(TEXT_ALIGNMENT_CENTER);
+ }
- setDayOfWeek(dayOfWeek);
- }
+ setDayOfWeek(dayOfWeek);
+ }
- public void setWeekDayFormatter(@Nullable final WeekDayFormatter formatter) {
- this.formatter = formatter == null ? WeekDayFormatter.DEFAULT : formatter;
- setDayOfWeek(dayOfWeek);
- }
+ public void setWeekDayFormatter(@Nullable final WeekDayFormatter formatter) {
+ this.formatter = formatter == null ? WeekDayFormatter.DEFAULT : formatter;
+ setDayOfWeek(dayOfWeek);
+ }
- public void setDayOfWeek(final DayOfWeek dayOfWeek) {
- this.dayOfWeek = dayOfWeek;
- setText(formatter.format(dayOfWeek));
- }
+ public void setDayOfWeek(final DayOfWeek dayOfWeek) {
+ this.dayOfWeek = dayOfWeek;
+ setText(formatter.format(dayOfWeek));
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java
index 413038da..227bfe17 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
import org.threeten.bp.temporal.ChronoUnit;
@@ -8,78 +9,81 @@
public class WeekPagerAdapter extends CalendarPagerAdapter {
- public WeekPagerAdapter(MaterialCalendarView mcv) {
- super(mcv);
- }
-
- @Override
- protected WeekView createView(int position) {
- return new WeekView(mcv, getItem(position), mcv.getFirstDayOfWeek(), showWeekDays);
- }
-
- @Override
- protected int indexOf(WeekView view) {
- CalendarDay week = view.getFirstViewDay();
- return getRangeIndex().indexOf(week);
- }
-
- @Override
- protected boolean isInstanceOfView(Object object) {
- return object instanceof WeekView;
- }
-
- @Override
- protected DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max) {
- return new Weekly(min, max, mcv.getFirstDayOfWeek());
- }
-
- public static class Weekly implements DateRangeIndex {
-
- /**
- * Minimum day of the first week to display.
- */
- private final CalendarDay min;
-
- /**
- * Number of weeks to show.
- */
- private final int count;
-
- /**
- * First day of the week to base the weeks on.
- */
- private final DayOfWeek firstDayOfWeek;
-
- public Weekly(
- @NonNull final CalendarDay min,
- @NonNull final CalendarDay max,
- final DayOfWeek firstDayOfWeek) {
- this.firstDayOfWeek = firstDayOfWeek;
- this.min = getFirstDayOfWeek(min);
- this.count = indexOf(max) + 1;
+ public WeekPagerAdapter(MaterialCalendarView mcv) {
+ super(mcv);
+ }
+
+ @Override
+ protected WeekView createView(int position) {
+ return new WeekView(mcv, getItem(position), mcv.getFirstDayOfWeek(), showWeekDays);
}
- @Override public int getCount() {
- return count;
+ @Override
+ protected int indexOf(WeekView view) {
+ CalendarDay week = view.getFirstViewDay();
+ return getRangeIndex().indexOf(week);
}
- @Override public int indexOf(final CalendarDay day) {
- final WeekFields weekFields = WeekFields.of(firstDayOfWeek, 1);
- final LocalDate temp = day.getDate().with(weekFields.dayOfWeek(), 1L);
- return (int) ChronoUnit.WEEKS.between(min.getDate(), temp);
+ @Override
+ protected boolean isInstanceOfView(Object object) {
+ return object instanceof WeekView;
}
- @Override public CalendarDay getItem(final int position) {
- return CalendarDay.from(min.getDate().plusWeeks(position));
+ @Override
+ protected DateRangeIndex createRangeIndex(CalendarDay min, CalendarDay max) {
+ return new Weekly(min, max, mcv.getFirstDayOfWeek());
}
- /**
- * Getting the first day of a week for a specific date based on a specific week day as first
- * day.
- */
- private CalendarDay getFirstDayOfWeek(@NonNull final CalendarDay day) {
- final LocalDate temp = day.getDate().with(WeekFields.of(firstDayOfWeek, 1).dayOfWeek(), 1L);
- return CalendarDay.from(temp);
+ public static class Weekly implements DateRangeIndex {
+
+ /**
+ * Minimum day of the first week to display.
+ */
+ private final CalendarDay min;
+
+ /**
+ * Number of weeks to show.
+ */
+ private final int count;
+
+ /**
+ * First day of the week to base the weeks on.
+ */
+ private final DayOfWeek firstDayOfWeek;
+
+ public Weekly(
+ @NonNull final CalendarDay min,
+ @NonNull final CalendarDay max,
+ final DayOfWeek firstDayOfWeek) {
+ this.firstDayOfWeek = firstDayOfWeek;
+ this.min = getFirstDayOfWeek(min);
+ this.count = indexOf(max) + 1;
+ }
+
+ @Override
+ public int getCount() {
+ return count;
+ }
+
+ @Override
+ public int indexOf(final CalendarDay day) {
+ final WeekFields weekFields = WeekFields.of(firstDayOfWeek, 1);
+ final LocalDate temp = day.getDate().with(weekFields.dayOfWeek(), 1L);
+ return (int) ChronoUnit.WEEKS.between(min.getDate(), temp);
+ }
+
+ @Override
+ public CalendarDay getItem(final int position) {
+ return CalendarDay.from(min.getDate().plusWeeks(position));
+ }
+
+ /**
+ * Getting the first day of a week for a specific date based on a specific week day as first
+ * day.
+ */
+ private CalendarDay getFirstDayOfWeek(@NonNull final CalendarDay day) {
+ final LocalDate temp = day.getDate().with(WeekFields.of(firstDayOfWeek, 1).dayOfWeek(), 1L);
+ return CalendarDay.from(temp);
+ }
}
- }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekView.java
index b9b87adb..d76a8dd8 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekView.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekView.java
@@ -1,8 +1,10 @@
package com.prolificinteractive.materialcalendarview;
import android.annotation.SuppressLint;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import java.util.Collection;
+
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
@@ -10,31 +12,35 @@
* Display a week of {@linkplain DayView}s and
* seven {@linkplain WeekDayView}s.
*/
-@SuppressLint("ViewConstructor") class WeekView extends CalendarPagerView {
-
- public WeekView(
- @NonNull final MaterialCalendarView view,
- final CalendarDay firstViewDay,
- final DayOfWeek firstDayOfWeek,
- final boolean showWeekDays) {
- super(view, firstViewDay, firstDayOfWeek, showWeekDays);
- }
-
- @Override protected void buildDayViews(
- final Collection dayViews,
- final LocalDate calendar) {
- LocalDate temp = calendar;
- for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
- addDayView(dayViews, temp);
- temp = temp.plusDays(1);
+@SuppressLint("ViewConstructor")
+class WeekView extends CalendarPagerView {
+
+ public WeekView(
+ @NonNull final MaterialCalendarView view,
+ final CalendarDay firstViewDay,
+ final DayOfWeek firstDayOfWeek,
+ final boolean showWeekDays) {
+ super(view, firstViewDay, firstDayOfWeek, showWeekDays);
}
- }
- @Override protected boolean isDayEnabled(CalendarDay day) {
- return true;
- }
+ @Override
+ protected void buildDayViews(
+ final Collection dayViews,
+ final LocalDate calendar) {
+ LocalDate temp = calendar;
+ for (int i = 0; i < DEFAULT_DAYS_IN_WEEK; i++) {
+ addDayView(dayViews, temp);
+ temp = temp.plusDays(1);
+ }
+ }
- @Override protected int getRows() {
- return showWeekDays ? DAY_NAMES_ROW + 1 : 1;
- }
+ @Override
+ protected boolean isDayEnabled(CalendarDay day) {
+ return true;
+ }
+
+ @Override
+ protected int getRows() {
+ return showWeekDays ? DAY_NAMES_ROW + 1 : 1;
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/ArrayWeekDayFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/ArrayWeekDayFormatter.java
index f3e052cd..71edc04a 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/ArrayWeekDayFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/ArrayWeekDayFormatter.java
@@ -7,25 +7,26 @@
*/
public class ArrayWeekDayFormatter implements WeekDayFormatter {
- private final CharSequence[] weekDayLabels;
+ private final CharSequence[] weekDayLabels;
- /**
- * @param weekDayLabels an array of 7 labels, starting with Sunday
- */
- public ArrayWeekDayFormatter(final CharSequence[] weekDayLabels) {
- if (weekDayLabels == null) {
- throw new IllegalArgumentException("Cannot be null");
+ /**
+ * @param weekDayLabels an array of 7 labels, starting with Sunday
+ */
+ public ArrayWeekDayFormatter(final CharSequence[] weekDayLabels) {
+ if (weekDayLabels == null) {
+ throw new IllegalArgumentException("Cannot be null");
+ }
+ if (weekDayLabels.length != 7) {
+ throw new IllegalArgumentException("Array must contain exactly 7 elements");
+ }
+ this.weekDayLabels = weekDayLabels;
}
- if (weekDayLabels.length != 7) {
- throw new IllegalArgumentException("Array must contain exactly 7 elements");
- }
- this.weekDayLabels = weekDayLabels;
- }
- /**
- * {@inheritDoc}
- */
- @Override public CharSequence format(final DayOfWeek dayOfWeek) {
- return weekDayLabels[dayOfWeek.getValue() - 1];
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CharSequence format(final DayOfWeek dayOfWeek) {
+ return weekDayLabels[dayOfWeek.getValue() - 1];
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatter.java
index 246964ae..5378b6ac 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatter.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview.format;
import java.util.Locale;
+
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.format.TextStyle;
@@ -10,10 +11,11 @@
* @see java.time.DayOfWeek#getDisplayName(java.time.format.TextStyle, Locale)
*/
public final class CalendarWeekDayFormatter implements WeekDayFormatter {
- /**
- * {@inheritDoc}
- */
- @Override public CharSequence format(final DayOfWeek dayOfWeek) {
- return dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault());
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CharSequence format(final DayOfWeek dayOfWeek) {
+ return dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault());
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatDayFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatDayFormatter.java
index cd8e1d37..dd0dcfa2 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatDayFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatDayFormatter.java
@@ -1,38 +1,83 @@
package com.prolificinteractive.materialcalendarview.format;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import com.prolificinteractive.materialcalendarview.CalendarDay;
+
import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Locale;
-import org.threeten.bp.format.DateTimeFormatter;
/**
* Format using a {@linkplain DateFormat} instance.
*/
public class DateFormatDayFormatter implements DayFormatter {
- private final DateTimeFormatter dateFormat;
-
- /**
- * Format using a default format
- */
- public DateFormatDayFormatter() {
- this(DateTimeFormatter.ofPattern(DEFAULT_FORMAT, Locale.getDefault()));
- }
-
- /**
- * Format using a specific {@linkplain DateFormat}
- *
- * @param format the format to use
- */
- public DateFormatDayFormatter(@NonNull final DateTimeFormatter format) {
- this.dateFormat = format;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override @NonNull public String format(@NonNull final CalendarDay day) {
- return dateFormat.format(day.getDate());
- }
+ //create singleton instance from DateFormatDayFormatter to avoid creating redundant instance for each DayView.
+ private static DateFormatDayFormatter dateFormatDayFormatter;
+ private DateFormat dateFormat;
+ private Locale lastKnownLocal;
+
+
+ /**
+ * Format using a default format
+ */
+ private DateFormatDayFormatter() {
+ this.dateFormat = new SimpleDateFormat("d", Locale.getDefault());
+ this.lastKnownLocal = Locale.getDefault();
+ }
+
+ /**
+ * Format using a specific {@linkplain DateFormat}
+ *
+ * @param format the format to use
+ */
+ private DateFormatDayFormatter(@NonNull final DateFormat format) {
+ this.dateFormat = format;
+ }
+
+ public static DateFormatDayFormatter getInstance() {
+ if (dateFormatDayFormatter == null)
+ dateFormatDayFormatter = new DateFormatDayFormatter();
+ else {
+ //if user change local and resume the activity the calender now will draw DayView text with the new Local.
+ Locale currentLocal = Locale.getDefault();
+ if (!dateFormatDayFormatter.getLastKnownLocal().equals(currentLocal)) {
+ dateFormatDayFormatter.setLastKnownLocal(currentLocal);
+ dateFormatDayFormatter.setDateFormat(new SimpleDateFormat("d", currentLocal));
+ }
+ }
+ return dateFormatDayFormatter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Locale getLastKnownLocal() {
+ return lastKnownLocal;
+ }
+
+ public void setLastKnownLocal(Locale lastKnownLocal) {
+ this.lastKnownLocal = lastKnownLocal;
+ }
+
+ public DateFormat getDateFormat() {
+ return dateFormat;
+ }
+
+ public void setDateFormat(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+
+ @Override
+ @NonNull
+ public String format(@NonNull final CalendarDay day) {
+ try {
+ return dateFormat.format(new SimpleDateFormat("yyyy-MM-dd").parse(day.getDate().toString()));
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java
index 3ba646c2..78901cfa 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview.format;
import com.prolificinteractive.materialcalendarview.CalendarDay;
+
import org.threeten.bp.format.DateTimeFormatter;
/**
@@ -8,28 +9,29 @@
*/
public class DateFormatTitleFormatter implements TitleFormatter {
- private final DateTimeFormatter dateFormat;
+ private final DateTimeFormatter dateFormat;
- /**
- * Format using {@link TitleFormatter#DEFAULT_FORMAT} for formatting.
- */
- public DateFormatTitleFormatter() {
- this(DateTimeFormatter.ofPattern(DEFAULT_FORMAT));
- }
+ /**
+ * Format using {@link TitleFormatter#DEFAULT_FORMAT} for formatting.
+ */
+ public DateFormatTitleFormatter() {
+ this(DateTimeFormatter.ofPattern(DEFAULT_FORMAT));
+ }
- /**
- * Format using a specified {@linkplain DateTimeFormatter}
- *
- * @param format the format to use
- */
- public DateFormatTitleFormatter(final DateTimeFormatter format) {
- this.dateFormat = format;
- }
+ /**
+ * Format using a specified {@linkplain DateTimeFormatter}
+ *
+ * @param format the format to use
+ */
+ public DateFormatTitleFormatter(final DateTimeFormatter format) {
+ this.dateFormat = format;
+ }
- /**
- * {@inheritDoc}
- */
- @Override public CharSequence format(final CalendarDay day) {
- return dateFormat.format(day.getDate());
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CharSequence format(final CalendarDay day) {
+ return dateFormat.format(day.getDate());
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DayFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DayFormatter.java
index 69fc11b8..b5950443 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DayFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DayFormatter.java
@@ -1,7 +1,9 @@
package com.prolificinteractive.materialcalendarview.format;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
+
import com.prolificinteractive.materialcalendarview.CalendarDay;
+
import java.text.SimpleDateFormat;
/**
@@ -9,21 +11,21 @@
*/
public interface DayFormatter {
- /**
- * Default format for displaying the day.
- */
- String DEFAULT_FORMAT = "d";
+ /**
+ * Default format for displaying the day.
+ */
+ String DEFAULT_FORMAT = "d";
- /**
- * Default implementation used by {@linkplain com.prolificinteractive.materialcalendarview.MaterialCalendarView}
- */
- DayFormatter DEFAULT = new DateFormatDayFormatter();
+ /**
+ * Default implementation used by {@linkplain com.prolificinteractive.materialcalendarview.MaterialCalendarView}
+ */
- /**
- * Format a given day into a string
- *
- * @param day the day
- * @return a label for the day
- */
- @NonNull String format(@NonNull CalendarDay day);
+ /**
+ * Format a given day into a string
+ *
+ * @param day the day
+ * @return a label for the day
+ */
+ @NonNull
+ String format(@NonNull CalendarDay day);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/MonthArrayTitleFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/MonthArrayTitleFormatter.java
index dfd58600..c1641bb7 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/MonthArrayTitleFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/MonthArrayTitleFormatter.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview.format;
import android.text.SpannableStringBuilder;
+
import com.prolificinteractive.materialcalendarview.CalendarDay;
/**
@@ -8,31 +9,31 @@
*/
public class MonthArrayTitleFormatter implements TitleFormatter {
- private final CharSequence[] monthLabels;
+ private final CharSequence[] monthLabels;
- /**
- * Format using an array of month labels
- *
- * @param monthLabels an array of 12 labels to use for months, starting with January
- */
- public MonthArrayTitleFormatter(CharSequence[] monthLabels) {
- if (monthLabels == null) {
- throw new IllegalArgumentException("Label array cannot be null");
- }
- if (monthLabels.length < 12) {
- throw new IllegalArgumentException("Label array is too short");
+ /**
+ * Format using an array of month labels
+ *
+ * @param monthLabels an array of 12 labels to use for months, starting with January
+ */
+ public MonthArrayTitleFormatter(CharSequence[] monthLabels) {
+ if (monthLabels == null) {
+ throw new IllegalArgumentException("Label array cannot be null");
+ }
+ if (monthLabels.length < 12) {
+ throw new IllegalArgumentException("Label array is too short");
+ }
+ this.monthLabels = monthLabels;
}
- this.monthLabels = monthLabels;
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public CharSequence format(CalendarDay day) {
- return new SpannableStringBuilder()
- .append(monthLabels[day.getMonth() - 1])
- .append(" ")
- .append(String.valueOf(day.getYear()));
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CharSequence format(CalendarDay day) {
+ return new SpannableStringBuilder()
+ .append(monthLabels[day.getMonth() - 1])
+ .append(" ")
+ .append(String.valueOf(day.getYear()));
+ }
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/TitleFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/TitleFormatter.java
index 9f2d0d9c..ba8cc6a0 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/TitleFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/TitleFormatter.java
@@ -7,15 +7,15 @@
*/
public interface TitleFormatter {
- String DEFAULT_FORMAT = "LLLL yyyy";
+ String DEFAULT_FORMAT = "LLLL yyyy";
- TitleFormatter DEFAULT = new DateFormatTitleFormatter();
+ TitleFormatter DEFAULT = new DateFormatTitleFormatter();
- /**
- * Converts the supplied day to a suitable month/year title
- *
- * @param day the day containing relevant month and year information
- * @return a label to display for the given month/year
- */
- CharSequence format(CalendarDay day);
+ /**
+ * Converts the supplied day to a suitable month/year title
+ *
+ * @param day the day containing relevant month and year information
+ * @return a label to display for the given month/year
+ */
+ CharSequence format(CalendarDay day);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/WeekDayFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/WeekDayFormatter.java
index 0546ed3b..229bec71 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/WeekDayFormatter.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/WeekDayFormatter.java
@@ -6,16 +6,16 @@
* Supply labels for a given day of the week.
*/
public interface WeekDayFormatter {
- /**
- * Convert a given day of the week into a label.
- *
- * @param dayOfWeek the day of the week as returned by {@linkplain DayOfWeek#getValue()}.
- * @return a label for the day of week.
- */
- CharSequence format(DayOfWeek dayOfWeek);
+ /**
+ * Default implementation used by {@linkplain com.prolificinteractive.materialcalendarview.MaterialCalendarView}
+ */
+ WeekDayFormatter DEFAULT = new CalendarWeekDayFormatter();
- /**
- * Default implementation used by {@linkplain com.prolificinteractive.materialcalendarview.MaterialCalendarView}
- */
- WeekDayFormatter DEFAULT = new CalendarWeekDayFormatter();
+ /**
+ * Convert a given day of the week into a label.
+ *
+ * @param dayOfWeek the day of the week as returned by {@linkplain DayOfWeek#getValue()}.
+ * @return a label for the day of week.
+ */
+ CharSequence format(DayOfWeek dayOfWeek);
}
diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/spans/DotSpan.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/spans/DotSpan.java
index f1a78d50..421f10f5 100644
--- a/library/src/main/java/com/prolificinteractive/materialcalendarview/spans/DotSpan.java
+++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/spans/DotSpan.java
@@ -9,71 +9,71 @@
*/
public class DotSpan implements LineBackgroundSpan {
- /**
- * Default radius used
- */
- public static final float DEFAULT_RADIUS = 3;
+ /**
+ * Default radius used
+ */
+ public static final float DEFAULT_RADIUS = 3;
- private final float radius;
- private final int color;
+ private final float radius;
+ private final int color;
- /**
- * Create a span to draw a dot using default radius and color
- *
- * @see #DotSpan(float, int)
- * @see #DEFAULT_RADIUS
- */
- public DotSpan() {
- this.radius = DEFAULT_RADIUS;
- this.color = 0;
- }
+ /**
+ * Create a span to draw a dot using default radius and color
+ *
+ * @see #DotSpan(float, int)
+ * @see #DEFAULT_RADIUS
+ */
+ public DotSpan() {
+ this.radius = DEFAULT_RADIUS;
+ this.color = 0;
+ }
- /**
- * Create a span to draw a dot using a specified color
- *
- * @param color color of the dot
- * @see #DotSpan(float, int)
- * @see #DEFAULT_RADIUS
- */
- public DotSpan(int color) {
- this.radius = DEFAULT_RADIUS;
- this.color = color;
- }
+ /**
+ * Create a span to draw a dot using a specified color
+ *
+ * @param color color of the dot
+ * @see #DotSpan(float, int)
+ * @see #DEFAULT_RADIUS
+ */
+ public DotSpan(int color) {
+ this.radius = DEFAULT_RADIUS;
+ this.color = color;
+ }
- /**
- * Create a span to draw a dot using a specified radius
- *
- * @param radius radius for the dot
- * @see #DotSpan(float, int)
- */
- public DotSpan(float radius) {
- this.radius = radius;
- this.color = 0;
- }
+ /**
+ * Create a span to draw a dot using a specified radius
+ *
+ * @param radius radius for the dot
+ * @see #DotSpan(float, int)
+ */
+ public DotSpan(float radius) {
+ this.radius = radius;
+ this.color = 0;
+ }
- /**
- * Create a span to draw a dot using a specified radius and color
- *
- * @param radius radius for the dot
- * @param color color of the dot
- */
- public DotSpan(float radius, int color) {
- this.radius = radius;
- this.color = color;
- }
+ /**
+ * Create a span to draw a dot using a specified radius and color
+ *
+ * @param radius radius for the dot
+ * @param color color of the dot
+ */
+ public DotSpan(float radius, int color) {
+ this.radius = radius;
+ this.color = color;
+ }
- @Override
- public void drawBackground(
- Canvas canvas, Paint paint,
- int left, int right, int top, int baseline, int bottom,
- CharSequence charSequence,
- int start, int end, int lineNum
- ) {
- int oldColor = paint.getColor();
- if (color != 0) {
- paint.setColor(color);
+ @Override
+ public void drawBackground(
+ Canvas canvas, Paint paint,
+ int left, int right, int top, int baseline, int bottom,
+ CharSequence charSequence,
+ int start, int end, int lineNum
+ ) {
+ int oldColor = paint.getColor();
+ if (color != 0) {
+ paint.setColor(color);
+ }
+ canvas.drawCircle((left + right) / 2, bottom + radius, radius, paint);
+ paint.setColor(oldColor);
}
- canvas.drawCircle((left + right) / 2, bottom + radius, radius, paint);
- paint.setColor(oldColor);
- }
}
diff --git a/library/src/main/res/color/mcv_text_date_dark.xml b/library/src/main/res/color/mcv_text_date_dark.xml
index a7d96ea0..7450bd47 100644
--- a/library/src/main/res/color/mcv_text_date_dark.xml
+++ b/library/src/main/res/color/mcv_text_date_dark.xml
@@ -1,15 +1,13 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/library/src/main/res/color/mcv_text_date_light.xml b/library/src/main/res/color/mcv_text_date_light.xml
index 48c42272..1190744b 100644
--- a/library/src/main/res/color/mcv_text_date_light.xml
+++ b/library/src/main/res/color/mcv_text_date_light.xml
@@ -1,15 +1,13 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/library/src/main/res/drawable-ldrtl/mcv_action_next.xml b/library/src/main/res/drawable-ldrtl/mcv_action_next.xml
index 0b624e03..318f41f3 100644
--- a/library/src/main/res/drawable-ldrtl/mcv_action_next.xml
+++ b/library/src/main/res/drawable-ldrtl/mcv_action_next.xml
@@ -1,11 +1,9 @@
-
+ android:viewportHeight="24.0">
+
diff --git a/library/src/main/res/drawable-ldrtl/mcv_action_previous.xml b/library/src/main/res/drawable-ldrtl/mcv_action_previous.xml
index 9080087f..d441199c 100644
--- a/library/src/main/res/drawable-ldrtl/mcv_action_previous.xml
+++ b/library/src/main/res/drawable-ldrtl/mcv_action_previous.xml
@@ -1,11 +1,9 @@
-
+ android:viewportHeight="24.0">
+
diff --git a/library/src/main/res/drawable/blue_circle.xml b/library/src/main/res/drawable/blue_circle.xml
new file mode 100644
index 00000000..38d8c968
--- /dev/null
+++ b/library/src/main/res/drawable/blue_circle.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/drawable/calendar_selector.xml b/library/src/main/res/drawable/calendar_selector.xml
new file mode 100644
index 00000000..a9997e9a
--- /dev/null
+++ b/library/src/main/res/drawable/calendar_selector.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/drawable/gray_circle.xml b/library/src/main/res/drawable/gray_circle.xml
new file mode 100644
index 00000000..8f8a51cf
--- /dev/null
+++ b/library/src/main/res/drawable/gray_circle.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/drawable/mcv_action_next.xml b/library/src/main/res/drawable/mcv_action_next.xml
index 9080087f..d441199c 100644
--- a/library/src/main/res/drawable/mcv_action_next.xml
+++ b/library/src/main/res/drawable/mcv_action_next.xml
@@ -1,11 +1,9 @@
-
+ android:viewportHeight="24.0">
+
diff --git a/library/src/main/res/drawable/mcv_action_previous.xml b/library/src/main/res/drawable/mcv_action_previous.xml
index 0b624e03..318f41f3 100644
--- a/library/src/main/res/drawable/mcv_action_previous.xml
+++ b/library/src/main/res/drawable/mcv_action_previous.xml
@@ -1,11 +1,9 @@
-
+ android:viewportHeight="24.0">
+
diff --git a/library/src/main/res/layout/calendar_view.xml b/library/src/main/res/layout/calendar_view.xml
index 4d8a2420..73300de9 100644
--- a/library/src/main/res/layout/calendar_view.xml
+++ b/library/src/main/res/layout/calendar_view.xml
@@ -6,40 +6,36 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
- android:orientation="horizontal"
- >
+ android:orientation="horizontal">
-
+
-
+
-
+
\ No newline at end of file
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
index 7cf664ba..87eb3441 100644
--- a/library/src/main/res/values/attrs.xml
+++ b/library/src/main/res/values/attrs.xml
@@ -1,70 +1,70 @@
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
diff --git a/library/src/main/res/values/dimens.xml b/library/src/main/res/values/dimens.xml
index 69a44add..18715a9f 100644
--- a/library/src/main/res/values/dimens.xml
+++ b/library/src/main/res/values/dimens.xml
@@ -1,5 +1,5 @@
- 4dp
- 4dp
+ 4dp
+ 4dp
diff --git a/library/src/main/res/values/ids.xml b/library/src/main/res/values/ids.xml
index cb6dcb22..e730c3de 100644
--- a/library/src/main/res/values/ids.xml
+++ b/library/src/main/res/values/ids.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml
index 05a93ca3..549c67f7 100644
--- a/library/src/main/res/values/strings.xml
+++ b/library/src/main/res/values/strings.xml
@@ -1,6 +1,6 @@
- Go to previous
- Go to next
- Calendar
+ Go to previous
+ Go to next
+ Calendar
diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml
index 70c5be03..4087ee2a 100644
--- a/library/src/main/res/values/styles.xml
+++ b/library/src/main/res/values/styles.xml
@@ -1,20 +1,17 @@
-
+
-
+
-
+
\ No newline at end of file
diff --git a/library/src/test/java/com/prolificinteractive/materialcalendarview/MonthlyRangeIndexTest.java b/library/src/test/java/com/prolificinteractive/materialcalendarview/MonthlyRangeIndexTest.java
index ceb160ff..4d00b893 100644
--- a/library/src/test/java/com/prolificinteractive/materialcalendarview/MonthlyRangeIndexTest.java
+++ b/library/src/test/java/com/prolificinteractive/materialcalendarview/MonthlyRangeIndexTest.java
@@ -16,119 +16,126 @@
public class MonthlyRangeIndexTest {
- @Test public void test400Years() {
- final CalendarDay january1816 = CalendarDay.from(1816, JANUARY.getValue(), 15);
- final CalendarDay january2216 = CalendarDay.from(2216, JANUARY.getValue(), 15);
- final CalendarDay april2018 = CalendarDay.from(2018, APRIL.getValue(), 1);
- final CalendarDay february1816 = CalendarDay.from(1816, FEBRUARY.getValue(), 1);
+ @Test
+ public void test400Years() {
+ final CalendarDay january1816 = CalendarDay.from(1816, JANUARY.getValue(), 15);
+ final CalendarDay january2216 = CalendarDay.from(2216, JANUARY.getValue(), 15);
+ final CalendarDay april2018 = CalendarDay.from(2018, APRIL.getValue(), 1);
+ final CalendarDay february1816 = CalendarDay.from(1816, FEBRUARY.getValue(), 1);
- final MonthPagerAdapter.Monthly monthly =
- new MonthPagerAdapter.Monthly(january1816, january2216);
+ final MonthPagerAdapter.Monthly monthly =
+ new MonthPagerAdapter.Monthly(january1816, january2216);
- assertThat(monthly.getCount(), equalTo((2216 - 1816) * 12 + 1));
+ assertThat(monthly.getCount(), equalTo((2216 - 1816) * 12 + 1));
- assertThat(monthly.getItem((2018 - 1816) * 12 + 3), equalTo(april2018));
- assertThat(monthly.getItem(1), equalTo(february1816));
+ assertThat(monthly.getItem((2018 - 1816) * 12 + 3), equalTo(april2018));
+ assertThat(monthly.getItem(1), equalTo(february1816));
- assertThat(monthly.indexOf(january1816), equalTo(0));
- assertThat(monthly.indexOf(february1816), equalTo(1));
- assertThat(monthly.indexOf(april2018), equalTo((2018 - 1816) * 12 + 3));
- assertThat(monthly.indexOf(january2216), equalTo((2216 - 1816) * 12));
- }
+ assertThat(monthly.indexOf(january1816), equalTo(0));
+ assertThat(monthly.indexOf(february1816), equalTo(1));
+ assertThat(monthly.indexOf(april2018), equalTo((2018 - 1816) * 12 + 3));
+ assertThat(monthly.indexOf(january2216), equalTo((2216 - 1816) * 12));
+ }
- @Test public void test3Years() {
- final CalendarDay may2016 = CalendarDay.from(2016, MAY.getValue(), 6);
- final CalendarDay april2017 = CalendarDay.from(2017, MAY.getValue(), 1);
- final CalendarDay june2019 = CalendarDay.from(2019, JUNE.getValue(), 1);
- final CalendarDay july2019 = CalendarDay.from(2019, JULY.getValue(), 21);
+ @Test
+ public void test3Years() {
+ final CalendarDay may2016 = CalendarDay.from(2016, MAY.getValue(), 6);
+ final CalendarDay april2017 = CalendarDay.from(2017, MAY.getValue(), 1);
+ final CalendarDay june2019 = CalendarDay.from(2019, JUNE.getValue(), 1);
+ final CalendarDay july2019 = CalendarDay.from(2019, JULY.getValue(), 21);
- final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2016, july2019);
+ final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2016, july2019);
- assertThat(monthly.getCount(), equalTo((2019 - 2016) * 12 + 3));
+ assertThat(monthly.getCount(), equalTo((2019 - 2016) * 12 + 3));
- assertThat(monthly.getItem(12), equalTo(april2017));
- assertThat(monthly.getItem((2019 - 2016) * 12 + 1), equalTo(june2019));
+ assertThat(monthly.getItem(12), equalTo(april2017));
+ assertThat(monthly.getItem((2019 - 2016) * 12 + 1), equalTo(june2019));
- assertThat(monthly.indexOf(may2016), equalTo(0));
- assertThat(monthly.indexOf(april2017), equalTo(12));
- assertThat(monthly.indexOf(june2019), equalTo((2019 - 2016) * 12 + 1));
- assertThat(monthly.indexOf(july2019), equalTo((2019 - 2016) * 12 + 2));
- }
+ assertThat(monthly.indexOf(may2016), equalTo(0));
+ assertThat(monthly.indexOf(april2017), equalTo(12));
+ assertThat(monthly.indexOf(june2019), equalTo((2019 - 2016) * 12 + 1));
+ assertThat(monthly.indexOf(july2019), equalTo((2019 - 2016) * 12 + 2));
+ }
- @Test public void test2Years() {
- final CalendarDay may2016 = CalendarDay.from(2016, MAY.getValue(), 31);
- final CalendarDay may2018 = CalendarDay.from(2018, MAY.getValue(), 1);
+ @Test
+ public void test2Years() {
+ final CalendarDay may2016 = CalendarDay.from(2016, MAY.getValue(), 31);
+ final CalendarDay may2018 = CalendarDay.from(2018, MAY.getValue(), 1);
- final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2016, may2018);
+ final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2016, may2018);
- assertThat(monthly.getCount(), equalTo(25));
+ assertThat(monthly.getCount(), equalTo(25));
- assertThat(monthly.getItem(25), equalTo(CalendarDay.from(2018, JUNE.getValue(), 1)));
+ assertThat(monthly.getItem(25), equalTo(CalendarDay.from(2018, JUNE.getValue(), 1)));
- assertThat(monthly.indexOf(may2016), equalTo(0));
- assertThat(monthly.indexOf(may2018), equalTo((2018 - 2016) * 12));
- }
+ assertThat(monthly.indexOf(may2016), equalTo(0));
+ assertThat(monthly.indexOf(may2018), equalTo((2018 - 2016) * 12));
+ }
- @Test public void test1Year() {
- final CalendarDay january2018 = CalendarDay.from(2018, JANUARY.getValue(), 1);
- final CalendarDay december2018 = CalendarDay.from(2018, DECEMBER.getValue(), 31);
- final CalendarDay last = CalendarDay.from(2018, DECEMBER.getValue(), 1);
+ @Test
+ public void test1Year() {
+ final CalendarDay january2018 = CalendarDay.from(2018, JANUARY.getValue(), 1);
+ final CalendarDay december2018 = CalendarDay.from(2018, DECEMBER.getValue(), 31);
+ final CalendarDay last = CalendarDay.from(2018, DECEMBER.getValue(), 1);
- final MonthPagerAdapter.Monthly monthly =
- new MonthPagerAdapter.Monthly(january2018, december2018);
+ final MonthPagerAdapter.Monthly monthly =
+ new MonthPagerAdapter.Monthly(january2018, december2018);
- assertThat(monthly.getCount(), equalTo(12));
+ assertThat(monthly.getCount(), equalTo(12));
- assertThat(monthly.getItem(0), equalTo(january2018));
- assertThat(monthly.getItem(11), equalTo(last));
+ assertThat(monthly.getItem(0), equalTo(january2018));
+ assertThat(monthly.getItem(11), equalTo(last));
- assertThat(monthly.indexOf(january2018), equalTo(0));
- assertThat(monthly.indexOf(last), equalTo(11));
- assertThat(monthly.indexOf(december2018), equalTo(11));
- }
+ assertThat(monthly.indexOf(january2018), equalTo(0));
+ assertThat(monthly.indexOf(last), equalTo(11));
+ assertThat(monthly.indexOf(december2018), equalTo(11));
+ }
- @Test public void test3Months() {
- final CalendarDay may2018 = CalendarDay.from(2018, MAY.getValue(), 25);
- final CalendarDay june2018 = CalendarDay.from(2018, JUNE.getValue(), 1);
- final CalendarDay july2018 = CalendarDay.from(2018, JULY.getValue(), 5);
+ @Test
+ public void test3Months() {
+ final CalendarDay may2018 = CalendarDay.from(2018, MAY.getValue(), 25);
+ final CalendarDay june2018 = CalendarDay.from(2018, JUNE.getValue(), 1);
+ final CalendarDay july2018 = CalendarDay.from(2018, JULY.getValue(), 5);
- final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2018, july2018);
+ final MonthPagerAdapter.Monthly monthly = new MonthPagerAdapter.Monthly(may2018, july2018);
- assertThat(monthly.getCount(), equalTo(3));
+ assertThat(monthly.getCount(), equalTo(3));
- assertThat(monthly.getItem(1), equalTo(june2018));
+ assertThat(monthly.getItem(1), equalTo(june2018));
- assertThat(monthly.indexOf(may2018), equalTo(0));
- assertThat(monthly.indexOf(june2018), equalTo(1));
- assertThat(monthly.indexOf(july2018), equalTo(2));
- }
+ assertThat(monthly.indexOf(may2018), equalTo(0));
+ assertThat(monthly.indexOf(june2018), equalTo(1));
+ assertThat(monthly.indexOf(july2018), equalTo(2));
+ }
- @Test public void test2Months() {
- final CalendarDay october2018 = CalendarDay.from(2018, OCTOBER.getValue(), 31);
- final CalendarDay november2018 = CalendarDay.from(2018, NOVEMBER.getValue(), 1);
+ @Test
+ public void test2Months() {
+ final CalendarDay october2018 = CalendarDay.from(2018, OCTOBER.getValue(), 31);
+ final CalendarDay november2018 = CalendarDay.from(2018, NOVEMBER.getValue(), 1);
- final MonthPagerAdapter.Monthly monthly =
- new MonthPagerAdapter.Monthly(october2018, november2018);
+ final MonthPagerAdapter.Monthly monthly =
+ new MonthPagerAdapter.Monthly(october2018, november2018);
- assertThat(monthly.getCount(), equalTo(2));
+ assertThat(monthly.getCount(), equalTo(2));
- assertThat(monthly.getItem(0), equalTo(CalendarDay.from(2018, OCTOBER.getValue(), 1)));
- assertThat(monthly.getItem(1), equalTo(CalendarDay.from(2018, NOVEMBER.getValue(), 1)));
+ assertThat(monthly.getItem(0), equalTo(CalendarDay.from(2018, OCTOBER.getValue(), 1)));
+ assertThat(monthly.getItem(1), equalTo(CalendarDay.from(2018, NOVEMBER.getValue(), 1)));
- assertThat(monthly.indexOf(october2018), equalTo(0));
- assertThat(monthly.indexOf(november2018), equalTo(1));
- }
+ assertThat(monthly.indexOf(october2018), equalTo(0));
+ assertThat(monthly.indexOf(november2018), equalTo(1));
+ }
- @Test public void test1Month() {
- final CalendarDay startOctober2018 = CalendarDay.from(2018, OCTOBER.getValue(), 5);
- final CalendarDay endOctober2018 = CalendarDay.from(2018, OCTOBER.getValue(), 25);
+ @Test
+ public void test1Month() {
+ final CalendarDay startOctober2018 = CalendarDay.from(2018, OCTOBER.getValue(), 5);
+ final CalendarDay endOctober2018 = CalendarDay.from(2018, OCTOBER.getValue(), 25);
- final MonthPagerAdapter.Monthly monthly =
- new MonthPagerAdapter.Monthly(endOctober2018, endOctober2018);
+ final MonthPagerAdapter.Monthly monthly =
+ new MonthPagerAdapter.Monthly(endOctober2018, endOctober2018);
- assertThat(monthly.getCount(), equalTo(1));
- assertThat(monthly.getItem(0), equalTo(CalendarDay.from(2018, OCTOBER.getValue(), 1)));
- assertThat(monthly.indexOf(startOctober2018), equalTo(0));
- assertThat(monthly.indexOf(endOctober2018), equalTo(0));
- }
+ assertThat(monthly.getCount(), equalTo(1));
+ assertThat(monthly.getItem(0), equalTo(CalendarDay.from(2018, OCTOBER.getValue(), 1)));
+ assertThat(monthly.indexOf(startOctober2018), equalTo(0));
+ assertThat(monthly.indexOf(endOctober2018), equalTo(0));
+ }
}
\ No newline at end of file
diff --git a/library/src/test/java/com/prolificinteractive/materialcalendarview/WeeklyRangeIndexTest.java b/library/src/test/java/com/prolificinteractive/materialcalendarview/WeeklyRangeIndexTest.java
index 2afdc5fd..763bb970 100644
--- a/library/src/test/java/com/prolificinteractive/materialcalendarview/WeeklyRangeIndexTest.java
+++ b/library/src/test/java/com/prolificinteractive/materialcalendarview/WeeklyRangeIndexTest.java
@@ -17,139 +17,147 @@
import static org.threeten.bp.Month.MARCH;
public class WeeklyRangeIndexTest {
- private static final int _2018 = 2018;
+ private static final int _2018 = 2018;
- @Test public void test1week() {
- final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 7);
- final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 13);
+ @Test
+ public void test1week() {
+ final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 7);
+ final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 13);
- final DateRangeIndex weekly =
- new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
+ final DateRangeIndex weekly =
+ new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
- assertThat(weekly.getCount(), equalTo(1));
+ assertThat(weekly.getCount(), equalTo(1));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
- assertThat(weekly.indexOf(endJanuary2018), equalTo(0));
- }
+ assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
+ assertThat(weekly.indexOf(endJanuary2018), equalTo(0));
+ }
- @Test public void test2weeksWith2Days() {
- final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 13);
- final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 14);
+ @Test
+ public void test2weeksWith2Days() {
+ final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 13);
+ final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 14);
- final DateRangeIndex weekly =
- new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
+ final DateRangeIndex weekly =
+ new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
- assertThat(weekly.getCount(), equalTo(2));
+ assertThat(weekly.getCount(), equalTo(2));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
- assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
- }
+ assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
+ assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
+ }
- @Test public void test2weeksWith2DaysWithDifferentFirstDay() {
- final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 10);
- final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 11);
+ @Test
+ public void test2weeksWith2DaysWithDifferentFirstDay() {
+ final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 10);
+ final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 11);
- final DateRangeIndex weekly =
- new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, THURSDAY);
+ final DateRangeIndex weekly =
+ new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, THURSDAY);
- assertThat(weekly.getCount(), equalTo(2));
+ assertThat(weekly.getCount(), equalTo(2));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 4)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 4)));
- assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
- assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
- }
+ assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
+ assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
+ }
- @Test public void test1weekStartingDifferentDays() {
- final CalendarDay startFebruary2018 = CalendarDay.from(_2018, FEBRUARY.getValue(), 7);
- final CalendarDay endFebruary2018 = CalendarDay.from(_2018, FEBRUARY.getValue(), 11);
+ @Test
+ public void test1weekStartingDifferentDays() {
+ final CalendarDay startFebruary2018 = CalendarDay.from(_2018, FEBRUARY.getValue(), 7);
+ final CalendarDay endFebruary2018 = CalendarDay.from(_2018, FEBRUARY.getValue(), 11);
- final DateRangeIndex monday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, MONDAY);
- final DateRangeIndex tuesday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, TUESDAY);
- final DateRangeIndex wednesday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, WEDNESDAY);
- final DateRangeIndex thursday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, THURSDAY);
- final DateRangeIndex friday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, FRIDAY);
- final DateRangeIndex saturday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, SATURDAY);
- final DateRangeIndex sunday =
- new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, SUNDAY);
+ final DateRangeIndex monday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, MONDAY);
+ final DateRangeIndex tuesday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, TUESDAY);
+ final DateRangeIndex wednesday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, WEDNESDAY);
+ final DateRangeIndex thursday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, THURSDAY);
+ final DateRangeIndex friday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, FRIDAY);
+ final DateRangeIndex saturday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, SATURDAY);
+ final DateRangeIndex sunday =
+ new WeekPagerAdapter.Weekly(startFebruary2018, endFebruary2018, SUNDAY);
- assertThat(monday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 5)));
- assertThat(tuesday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 6)));
- assertThat(wednesday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 7)));
- assertThat(thursday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 1)));
- assertThat(friday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 2)));
- assertThat(saturday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 3)));
- assertThat(sunday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 4)));
- }
+ assertThat(monday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 5)));
+ assertThat(tuesday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 6)));
+ assertThat(wednesday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 7)));
+ assertThat(thursday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 1)));
+ assertThat(friday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 2)));
+ assertThat(saturday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 3)));
+ assertThat(sunday.getItem(0), equalTo(CalendarDay.from(_2018, FEBRUARY.getValue(), 4)));
+ }
- @Test public void test2weeks() {
- final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
- final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 18);
+ @Test
+ public void test2weeks() {
+ final CalendarDay startJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
+ final CalendarDay endJanuary2018 = CalendarDay.from(_2018, JANUARY.getValue(), 18);
- final DateRangeIndex weekly =
- new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
+ final DateRangeIndex weekly =
+ new WeekPagerAdapter.Weekly(startJanuary2018, endJanuary2018, SUNDAY);
- assertThat(weekly.getCount(), equalTo(2));
+ assertThat(weekly.getCount(), equalTo(2));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.getItem(1), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 14)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(1), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 14)));
- assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
- assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
- }
+ assertThat(weekly.indexOf(startJanuary2018), equalTo(0));
+ assertThat(weekly.indexOf(endJanuary2018), equalTo(1));
+ }
- @Test public void test10weeks() {
- final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
- final CalendarDay march2018 = CalendarDay.from(_2018, MARCH.getValue(), 12);
+ @Test
+ public void test10weeks() {
+ final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
+ final CalendarDay march2018 = CalendarDay.from(_2018, MARCH.getValue(), 12);
- final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, march2018, SUNDAY);
+ final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, march2018, SUNDAY);
- assertThat(weekly.getCount(), equalTo(10));
+ assertThat(weekly.getCount(), equalTo(10));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.getItem(9), equalTo(CalendarDay.from(_2018, MARCH.getValue(), 11)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(9), equalTo(CalendarDay.from(_2018, MARCH.getValue(), 11)));
- assertThat(weekly.indexOf(january2018), equalTo(0));
- assertThat(weekly.indexOf(march2018), equalTo(9));
- }
+ assertThat(weekly.indexOf(january2018), equalTo(0));
+ assertThat(weekly.indexOf(march2018), equalTo(9));
+ }
- @Test public void test52weeks() {
- final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
- final CalendarDay january2019 = CalendarDay.from(2019, JANUARY.getValue(), 3);
+ @Test
+ public void test52weeks() {
+ final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 9);
+ final CalendarDay january2019 = CalendarDay.from(2019, JANUARY.getValue(), 3);
- final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, january2019, SUNDAY);
+ final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, january2019, SUNDAY);
- assertThat(weekly.getCount(), equalTo(52));
+ assertThat(weekly.getCount(), equalTo(52));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.getItem(51), equalTo(CalendarDay.from(2018, DECEMBER.getValue(), 30)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(51), equalTo(CalendarDay.from(2018, DECEMBER.getValue(), 30)));
- assertThat(weekly.indexOf(january2018), equalTo(0));
- assertThat(weekly.indexOf(january2019), equalTo(51));
- }
+ assertThat(weekly.indexOf(january2018), equalTo(0));
+ assertThat(weekly.indexOf(january2019), equalTo(51));
+ }
- @Test public void test1000weeks() {
- final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 11);
- final CalendarDay march2037 = CalendarDay.from(2037, MARCH.getValue(), 1);
+ @Test
+ public void test1000weeks() {
+ final CalendarDay january2018 = CalendarDay.from(_2018, JANUARY.getValue(), 11);
+ final CalendarDay march2037 = CalendarDay.from(2037, MARCH.getValue(), 1);
- final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, march2037, SUNDAY);
+ final DateRangeIndex weekly = new WeekPagerAdapter.Weekly(january2018, march2037, SUNDAY);
- assertThat(weekly.getCount(), equalTo(1000));
+ assertThat(weekly.getCount(), equalTo(1000));
- assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
- assertThat(weekly.getItem(999), equalTo(CalendarDay.from(2037, MARCH.getValue(), 1)));
+ assertThat(weekly.getItem(0), equalTo(CalendarDay.from(_2018, JANUARY.getValue(), 7)));
+ assertThat(weekly.getItem(999), equalTo(CalendarDay.from(2037, MARCH.getValue(), 1)));
- assertThat(weekly.indexOf(january2018), equalTo(0));
- assertThat(weekly.indexOf(march2037), equalTo(999));
- }
+ assertThat(weekly.indexOf(january2018), equalTo(0));
+ assertThat(weekly.indexOf(march2037), equalTo(999));
+ }
}
\ No newline at end of file
diff --git a/library/src/test/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatterTest.java b/library/src/test/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatterTest.java
index 132db575..27c2173f 100644
--- a/library/src/test/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatterTest.java
+++ b/library/src/test/java/com/prolificinteractive/materialcalendarview/format/CalendarWeekDayFormatterTest.java
@@ -1,6 +1,7 @@
package com.prolificinteractive.materialcalendarview.format;
import java.util.Locale;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -11,44 +12,53 @@
public class CalendarWeekDayFormatterTest {
- public CalendarWeekDayFormatter formatter;
- public Locale defaultLocaleOriginal;
+ public CalendarWeekDayFormatter formatter;
+ public Locale defaultLocaleOriginal;
- @Before public void setUp() {
- defaultLocaleOriginal = Locale.getDefault();
- Locale.setDefault(Locale.ENGLISH);
- formatter = new CalendarWeekDayFormatter();
- }
+ @Before
+ public void setUp() {
+ defaultLocaleOriginal = Locale.getDefault();
+ Locale.setDefault(Locale.ENGLISH);
+ formatter = new CalendarWeekDayFormatter();
+ }
- @After public void tearDown() {
- Locale.setDefault(defaultLocaleOriginal);
- }
+ @After
+ public void tearDown() {
+ Locale.setDefault(defaultLocaleOriginal);
+ }
- @Test public void testFormattedDayOfWeek_Sunday() {
- assertThat(formatter.format(DayOfWeek.SUNDAY).toString(), is("Sun"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Sunday() {
+ assertThat(formatter.format(DayOfWeek.SUNDAY).toString(), is("Sun"));
+ }
- @Test public void testFormattedDayOfWeek_Monday() {
- assertThat(formatter.format(DayOfWeek.MONDAY).toString(), is("Mon"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Monday() {
+ assertThat(formatter.format(DayOfWeek.MONDAY).toString(), is("Mon"));
+ }
- @Test public void testFormattedDayOfWeek_Tuesday() {
- assertThat(formatter.format(DayOfWeek.TUESDAY).toString(), is("Tue"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Tuesday() {
+ assertThat(formatter.format(DayOfWeek.TUESDAY).toString(), is("Tue"));
+ }
- @Test public void testFormattedDayOfWeek_Wednesday() {
- assertThat(formatter.format(DayOfWeek.WEDNESDAY).toString(), is("Wed"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Wednesday() {
+ assertThat(formatter.format(DayOfWeek.WEDNESDAY).toString(), is("Wed"));
+ }
- @Test public void testFormattedDayOfWeek_Thursday() {
- assertThat(formatter.format(DayOfWeek.THURSDAY).toString(), is("Thu"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Thursday() {
+ assertThat(formatter.format(DayOfWeek.THURSDAY).toString(), is("Thu"));
+ }
- @Test public void testFormattedDayOfWeek_Friday() {
- assertThat(formatter.format(DayOfWeek.FRIDAY).toString(), is("Fri"));
- }
+ @Test
+ public void testFormattedDayOfWeek_Friday() {
+ assertThat(formatter.format(DayOfWeek.FRIDAY).toString(), is("Fri"));
+ }
- @Test public void shouldReturnCorrectFormattedEnglishTextOfSaturday() {
- assertThat(formatter.format(DayOfWeek.SATURDAY).toString(), is("Sat"));
- }
+ @Test
+ public void shouldReturnCorrectFormattedEnglishTextOfSaturday() {
+ assertThat(formatter.format(DayOfWeek.SATURDAY).toString(), is("Sat"));
+ }
}
\ No newline at end of file
diff --git a/sample/.gitignore b/sample/.gitignore
deleted file mode 100644
index 796b96d1..00000000
--- a/sample/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/sample/README.md b/sample/README.md
deleted file mode 100644
index fb08c91e..00000000
--- a/sample/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Material CalendarView Sample App
-================================
-
-The sample app contains a mixture of implementations to help test and debug during development,
-and to help new users understand how to implement some functionality.
\ No newline at end of file
diff --git a/sample/build.gradle b/sample/build.gradle
deleted file mode 100644
index 01c0408f..00000000
--- a/sample/build.gradle
+++ /dev/null
@@ -1,37 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
-
- defaultConfig {
- applicationId "com.prolificinteractive.materialcalendarview.sample"
-
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
-
- versionCode 1
- versionName "1.0"
- }
-
- lintOptions {
- abortOnError false
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
-
-dependencies {
- // You should use the commented out line below in you're application.
- // We depend on the source directly here so that development is easier.
- implementation project(':library')
- //compile 'com.prolificinteractive:material-calendarview:1.4.3'
-
- implementation rootProject.ext.threeTenAbp
- implementation rootProject.ext.supportAppCompat
- implementation rootProject.ext.recyclerviewV7
- implementation rootProject.ext.butterknife
- annotationProcessor rootProject.ext.butterknifeCompiler
-}
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
deleted file mode 100644
index db4839bb..00000000
--- a/sample/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,294 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivity.java
deleted file mode 100644
index e3168c13..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import android.widget.TextView;
-import android.widget.Toast;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateLongClickListener;
-import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
-import com.prolificinteractive.materialcalendarview.OnMonthChangedListener;
-import org.threeten.bp.format.DateTimeFormatter;
-
-/**
- * Shows off the most basic usage
- */
-public class BasicActivity extends AppCompatActivity
- implements OnDateSelectedListener, OnMonthChangedListener, OnDateLongClickListener {
-
- private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, d MMM yyyy");
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- @BindView(R.id.textView)
- TextView textView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic);
- ButterKnife.bind(this);
-
- widget.setOnDateChangedListener(this);
- widget.setOnDateLongClickListener(this);
- widget.setOnMonthChangedListener(this);
-
- //Setup initial text
- textView.setText("No Selection");
- }
-
- @Override
- public void onDateSelected(
- @NonNull MaterialCalendarView widget,
- @NonNull CalendarDay date,
- boolean selected) {
- textView.setText(selected ? FORMATTER.format(date.getDate()) : "No Selection");
- }
-
- @Override
- public void onDateLongClick(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date) {
- final String text = String.format("%s is available", FORMATTER.format(date.getDate()));
- Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
- //noinspection ConstantConditions
- getSupportActionBar().setTitle(FORMATTER.format(date.getDate()));
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java
deleted file mode 100644
index d67a5b8b..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.graphics.Color;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
-import com.prolificinteractive.materialcalendarview.sample.decorators.EventDecorator;
-import com.prolificinteractive.materialcalendarview.sample.decorators.HighlightWeekendsDecorator;
-import com.prolificinteractive.materialcalendarview.sample.decorators.MySelectorDecorator;
-import com.prolificinteractive.materialcalendarview.sample.decorators.OneDayDecorator;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.Month;
-
-/**
- * Shows off the most basic usage
- */
-public class BasicActivityDecorated extends AppCompatActivity implements OnDateSelectedListener {
-
- private final OneDayDecorator oneDayDecorator = new OneDayDecorator();
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic);
- ButterKnife.bind(this);
-
- widget.setOnDateChangedListener(this);
- widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL);
-
- final LocalDate instance = LocalDate.now();
- widget.setSelectedDate(instance);
-
- final LocalDate min = LocalDate.of(instance.getYear(), Month.JANUARY, 1);
- final LocalDate max = LocalDate.of(instance.getYear(), Month.DECEMBER, 31);
-
- widget.state().edit().setMinimumDate(min).setMaximumDate(max).commit();
-
- widget.addDecorators(
- new MySelectorDecorator(this),
- new HighlightWeekendsDecorator(),
- oneDayDecorator
- );
-
- new ApiSimulator().executeOnExecutor(Executors.newSingleThreadExecutor());
- }
-
- @Override
- public void onDateSelected(
- @NonNull MaterialCalendarView widget,
- @NonNull CalendarDay date,
- boolean selected) {
- //If you change a decorate, you need to invalidate decorators
- oneDayDecorator.setDate(date.getDate());
- widget.invalidateDecorators();
- }
-
- /**
- * Simulate an API call to show how to add decorators
- */
- private class ApiSimulator extends AsyncTask> {
-
- @Override
- protected List doInBackground(@NonNull Void... voids) {
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- LocalDate temp = LocalDate.now().minusMonths(2);
- final ArrayList dates = new ArrayList<>();
- for (int i = 0; i < 30; i++) {
- final CalendarDay day = CalendarDay.from(temp);
- dates.add(day);
- temp = temp.plusDays(5);
- }
-
- return dates;
- }
-
- @Override
- protected void onPostExecute(@NonNull List calendarDays) {
- super.onPostExecute(calendarDays);
-
- if (isFinishing()) {
- return;
- }
-
- widget.addDecorator(new EventDecorator(Color.RED, calendarDays));
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomTileDimensions.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomTileDimensions.java
deleted file mode 100644
index 8d60de5e..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomTileDimensions.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.content.DialogInterface;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.widget.LinearLayout;
-import android.widget.NumberPicker;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-
-/**
- * Created by maragues on 17/06/16.
- */
-public class CustomTileDimensions extends AppCompatActivity {
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- private int currentTileWidth;
- private int currentTileHeight;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_custom_tile);
- ButterKnife.bind(this);
-
- currentTileWidth = MaterialCalendarView.DEFAULT_TILE_SIZE_DP;
- currentTileHeight = MaterialCalendarView.DEFAULT_TILE_SIZE_DP;
-
- widget.addDecorator(new TodayDecorator());
- }
-
- @OnClick(R.id.custom_tile_match_parent)
- public void onMatchParentClick() {
- widget.setTileSize(LinearLayout.LayoutParams.MATCH_PARENT);
- }
-
- @OnClick(R.id.custom_tile_width_match_parent)
- public void onWidthMatchParentClick() {
- widget.setTileWidth(LinearLayout.LayoutParams.MATCH_PARENT);
- }
-
- @OnClick(R.id.custom_tile_height_match_parent)
- public void onHeightMatchParentClick() {
- widget.setTileHeight(LinearLayout.LayoutParams.MATCH_PARENT);
- }
-
- @OnClick(R.id.custom_tile_width_size)
- public void onWidthClick() {
- final NumberPicker view = new NumberPicker(this);
- view.setMinValue(24);
- view.setMaxValue(64);
- view.setWrapSelectorWheel(false);
- view.setValue(currentTileWidth);
- new AlertDialog.Builder(this)
- .setView(view)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(@NonNull DialogInterface dialog, int which) {
- currentTileWidth = view.getValue();
- widget.setTileWidthDp(currentTileWidth);
- }
- })
- .show();
- }
-
- @OnClick(R.id.custom_tile_height_size)
- public void onHeightClick() {
- final NumberPicker view = new NumberPicker(this);
- view.setMinValue(24);
- view.setMaxValue(64);
- view.setWrapSelectorWheel(false);
- view.setValue(currentTileHeight);
- new AlertDialog.Builder(this)
- .setView(view)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(@NonNull DialogInterface dialog, int which) {
- currentTileHeight = view.getValue();
- widget.setTileHeightDp(currentTileHeight);
- }
- })
- .show();
- }
-
- private class TodayDecorator implements DayViewDecorator {
-
- private final CalendarDay today;
- private final Drawable backgroundDrawable;
-
- public TodayDecorator() {
- today = CalendarDay.today();
- backgroundDrawable = getResources().getDrawable(R.drawable.today_circle_background);
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return today.equals(day);
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.setBackgroundDrawable(backgroundDrawable);
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java
deleted file mode 100644
index 2cdbda24..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.util.TypedValue;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.CalendarMode;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.format.ArrayWeekDayFormatter;
-import com.prolificinteractive.materialcalendarview.format.MonthArrayTitleFormatter;
-import org.threeten.bp.DayOfWeek;
-
-public class CustomizeCodeActivity extends AppCompatActivity {
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic);
- ButterKnife.bind(this);
-
- widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL);
- widget.setLeftArrow(R.drawable.ic_arrow_back);
- widget.setRightArrow(R.drawable.ic_arrow_forward);
- widget.setSelectionColor(getResources().getColor(R.color.sample_primary));
- widget.setWeekDayTextAppearance(R.style.CustomTextAppearance);
- widget.setHeaderTextAppearance(R.style.CustomTextAppearance);
- widget.setDateTextAppearance(R.style.CustomTextAppearance);
- widget.setTitleFormatter(new MonthArrayTitleFormatter(getResources().getTextArray(R.array.custom_months)));
- widget.setWeekDayFormatter(new ArrayWeekDayFormatter(getResources().getTextArray(R.array.custom_weekdays)));
- widget.setTileSize((int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- 36,
- getResources().getDisplayMetrics()
- ));
- widget.setTitleAnimationOrientation(MaterialCalendarView.VERTICAL);
-
- CalendarDay today = CalendarDay.from(2016, 5, 2);
- widget.setCurrentDate(today);
- widget.setSelectedDate(today);
-
- widget.state().edit()
- .setFirstDayOfWeek(DayOfWeek.WEDNESDAY)
- .setMinimumDate(CalendarDay.from(2016, 4, 3))
- .setMaximumDate(CalendarDay.from(2016, 5, 12))
- .setCalendarDisplayMode(CalendarMode.WEEKS)
- .commit();
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeXmlActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeXmlActivity.java
deleted file mode 100644
index baf33683..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeXmlActivity.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-
-public class CustomizeXmlActivity extends AppCompatActivity {
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_customization);
- ButterKnife.bind(this);
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DialogsActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DialogsActivity.java
deleted file mode 100644
index befb6ef9..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DialogsActivity.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.app.AppCompatDialogFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
-import org.threeten.bp.format.DateTimeFormatter;
-
-/**
- * Shows off the most basic usage
- */
-public class DialogsActivity extends AppCompatActivity {
-
- private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, d MMM yyyy");
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dialogs);
- ButterKnife.bind(this);
- }
-
- @OnClick(R.id.button_normal_dialog)
- void onNormalDialogClick() {
- new SimpleDialogFragment().show(getSupportFragmentManager(), "test-normal");
- }
-
- @OnClick(R.id.button_simple_dialog)
- void onSimpleCalendarDialogClick() {
- new SimpleCalendarDialogFragment().show(getSupportFragmentManager(), "test-simple-calendar");
- }
-
- public static class SimpleDialogFragment extends AppCompatDialogFragment {
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.title_activity_dialogs)
- .setMessage("Test Dialog")
- .setPositiveButton(android.R.string.ok, null)
- .create();
- }
- }
-
- public static class SimpleCalendarDialogFragment extends AppCompatDialogFragment
- implements OnDateSelectedListener {
-
- private TextView textView;
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- LayoutInflater inflater = getActivity().getLayoutInflater();
-
- //inflate custom layout and get views
- //pass null as parent view because will be in dialog layout
- View view = inflater.inflate(R.layout.dialog_basic, null);
-
- textView = view.findViewById(R.id.textView);
-
- MaterialCalendarView widget = view.findViewById(R.id.calendarView);
-
- widget.setOnDateChangedListener(this);
-
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.title_activity_dialogs)
- .setView(view)
- .setPositiveButton(android.R.string.ok, null)
- .create();
- }
-
- @Override
- public void onDateSelected(
- @NonNull MaterialCalendarView widget,
- @NonNull CalendarDay date,
- boolean selected) {
- textView.setText(FORMATTER.format(date.getDate()));
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java
deleted file mode 100644
index d164553b..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.Month;
-
-/**
- * Show off setting min and max dates and disabling individual days
- */
-public class DisableDaysActivity extends AppCompatActivity {
-
- @BindView(R.id.calendarView) MaterialCalendarView widget;
-
- @Override protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic);
- ButterKnife.bind(this);
-
- // Add a decorator to disable prime numbered days
- widget.addDecorator(new PrimeDayDisableDecorator());
- // Add a second decorator that explicitly enables days <= 10. This will work because
- // decorators are applied in order, and the system allows re-enabling
- widget.addDecorator(new EnableOneToTenDecorator());
-
- final LocalDate calendar = LocalDate.now();
- widget.setSelectedDate(calendar);
-
- final LocalDate min = LocalDate.of(calendar.getYear(), Month.JANUARY, 1);
- final LocalDate max = LocalDate.of(calendar.getYear() + 1, Month.OCTOBER, 31);
-
- widget.state().edit()
- .setMinimumDate(min)
- .setMaximumDate(max)
- .commit();
- }
-
- private static class PrimeDayDisableDecorator implements DayViewDecorator {
-
- @Override public boolean shouldDecorate(final CalendarDay day) {
- return PRIME_TABLE[day.getDay()];
- }
-
- @Override public void decorate(final DayViewFacade view) {
- view.setDaysDisabled(true);
- }
-
- private static boolean[] PRIME_TABLE = {
- false, // 0?
- false,
- true, // 2
- true, // 3
- false,
- true, // 5
- false,
- true, // 7
- false,
- false,
- false,
- true, // 11
- false,
- true, // 13
- false,
- false,
- false,
- true, // 17
- false,
- true, // 19
- false,
- false,
- false,
- true, // 23
- false,
- false,
- false,
- false,
- false,
- true, // 29
- false,
- true, // 31
- false,
- false,
- false, //PADDING
- };
- }
-
- private static class EnableOneToTenDecorator implements DayViewDecorator {
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return day.getDay() <= 10;
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.setDaysDisabled(false);
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java
deleted file mode 100644
index 516cdd37..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java
+++ /dev/null
@@ -1,345 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.app.DatePickerDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.graphics.Color;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.transition.TransitionManager;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.LinearLayout;
-import android.widget.NumberPicker;
-import android.widget.Toast;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnCheckedChanged;
-import butterknife.OnClick;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.CalendarMode;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateLongClickListener;
-import java.util.Random;
-import org.threeten.bp.DayOfWeek;
-import org.threeten.bp.format.DateTimeFormatter;
-
-public class DynamicSettersActivity extends AppCompatActivity implements OnDateLongClickListener {
-
- private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, d MMM yyyy");
-
- @BindView(R.id.calendarView) MaterialCalendarView widget;
- @BindView(R.id.animate_mode_transition) CheckBox animateModeTransition;
- @BindView(R.id.parent) ViewGroup parent;
-
- private int currentTileSize;
- private int currentTileWidth;
- private int currentTileHeight;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dynamic_setters);
- ButterKnife.bind(this);
-
- currentTileSize = MaterialCalendarView.DEFAULT_TILE_SIZE_DP;
- currentTileWidth = MaterialCalendarView.DEFAULT_TILE_SIZE_DP;
- currentTileHeight = MaterialCalendarView.DEFAULT_TILE_SIZE_DP;
-
- widget.setOnTitleClickListener(new View.OnClickListener() {
- @Override
- public void onClick(final View view) {
- Toast.makeText(DynamicSettersActivity.this, R.string.today, Toast.LENGTH_SHORT).show();
- }
- });
-
- widget.setOnDateLongClickListener(this);
- }
-
- @OnClick(R.id.button_other_dates)
- void onOtherDatesClicked() {
- CharSequence[] items = {
- "Other Months",
- "Out Of Range",
- "Decorated Disabled",
- "Select days outside month"
- };
- final int[] itemValues = {
- MaterialCalendarView.SHOW_OTHER_MONTHS,
- MaterialCalendarView.SHOW_OUT_OF_RANGE,
- MaterialCalendarView.SHOW_DECORATED_DISABLED,
- };
- int showOtherDates = widget.getShowOtherDates();
-
- boolean[] initSelections = {
- MaterialCalendarView.showOtherMonths(showOtherDates),
- MaterialCalendarView.showOutOfRange(showOtherDates),
- MaterialCalendarView.showDecoratedDisabled(showOtherDates),
- widget.allowClickDaysOutsideCurrentMonth()
- };
- new AlertDialog.Builder(this)
- .setTitle("Show Other Dates")
- .setMultiChoiceItems(
- items,
- initSelections,
- new DialogInterface.OnMultiChoiceClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which, boolean isChecked) {
- if (which < 3) {
- int showOtherDates = widget.getShowOtherDates();
- if (isChecked) {
- //Set flag
- showOtherDates |= itemValues[which];
- } else {
- //Unset flag
- showOtherDates &= ~itemValues[which];
- }
- widget.setShowOtherDates(showOtherDates);
- } else if (which == 3) {
- widget.setAllowClickDaysOutsideCurrentMonth(isChecked);
- }
- }
- }
- )
- .setPositiveButton(android.R.string.ok, null)
- .show();
- }
-
- @OnCheckedChanged(R.id.enable_save_current_position)
- void onSaveCurrentPositionChecked(boolean checked) {
- widget.state().edit().isCacheCalendarPositionEnabled(checked).commit();
- }
-
- @OnCheckedChanged(R.id.show_week_days)
- void onShowWeekDaysChecked(boolean checked) {
- widget.state().edit().setShowWeekDays(checked).commit();
- }
-
- @OnCheckedChanged(R.id.check_text_appearance)
- void onTextAppearanceChecked(boolean checked) {
- if (checked) {
- widget.setHeaderTextAppearance(R.style.TextAppearance_AppCompat_Large);
- widget.setDateTextAppearance(R.style.TextAppearance_AppCompat_Medium);
- widget.setWeekDayTextAppearance(R.style.TextAppearance_AppCompat_Medium);
- } else {
- widget.setHeaderTextAppearance(R.style.TextAppearance_MaterialCalendarWidget_Header);
- widget.setDateTextAppearance(R.style.TextAppearance_MaterialCalendarWidget_Date);
- widget.setWeekDayTextAppearance(R.style.TextAppearance_MaterialCalendarWidget_WeekDay);
- }
- widget.setShowOtherDates(
- checked ? MaterialCalendarView.SHOW_ALL : MaterialCalendarView.SHOW_NONE);
- }
-
- @OnCheckedChanged(R.id.check_page_enabled)
- void onPageEnabledChecked(boolean checked) {
- widget.setPagingEnabled(checked);
- }
-
- @OnCheckedChanged(R.id.dynamic_height_enabled)
- void onDynamicHeightChecked(boolean checked) {
- widget.setDynamicHeightEnabled(checked);
- }
-
- @OnClick(R.id.button_previous)
- void onPreviousClicked() {
- widget.goToPrevious();
- }
-
- @OnClick(R.id.button_next)
- void onNextClicked() {
- widget.goToNext();
- }
-
- @OnClick(R.id.button_min_date)
- void onMinClicked() {
- showDatePickerDialog(this, widget.getMinimumDate(),
- (view, year, monthOfYear, dayOfMonth) ->
- widget.state().edit()
- .setMinimumDate(CalendarDay.from(year, monthOfYear + 1, dayOfMonth))
- .commit()
- );
- }
-
- @OnClick(R.id.button_max_date)
- void onMaxClicked() {
- showDatePickerDialog(this, widget.getMaximumDate(),
- (view, year, monthOfYear, dayOfMonth) ->
- widget.state().edit()
- .setMaximumDate(CalendarDay.from(year, monthOfYear + 1, dayOfMonth))
- .commit()
- );
- }
-
- @OnClick(R.id.button_selected_date)
- void onSelectedClicked() {
- showDatePickerDialog(this, widget.getSelectedDate(),
- (view, year, monthOfYear, dayOfMonth) ->
- widget.setSelectedDate(CalendarDay.from(year, monthOfYear + 1, dayOfMonth))
- );
- }
-
- @OnClick(R.id.button_toggle_topbar)
- void onToggleTopBarClicked() {
- widget.setTopbarVisible(!widget.getTopbarVisible());
- }
-
- Random random = new Random();
-
- @OnClick(R.id.button_set_colors)
- void onColorsClicked() {
- int color = Color.HSVToColor(new float[] {
- random.nextFloat() * 360,
- 1f,
- 0.75f
- });
- widget.setSelectionColor(color);
- }
-
- @OnClick(R.id.button_set_tile_size)
- void onTileSizeClicked() {
- final NumberPicker view = new NumberPicker(this);
- view.setMinValue(24);
- view.setMaxValue(64);
- view.setWrapSelectorWheel(false);
- view.setValue(currentTileSize);
- new AlertDialog.Builder(this)
- .setView(view)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(@NonNull DialogInterface dialog, int which) {
- currentTileSize = view.getValue();
- widget.setTileSizeDp(currentTileSize);
- }
- })
- .show();
- }
-
- @OnClick(R.id.button_set_width_height)
- void onTileWidthHeightClicked() {
- final LinearLayout layout = new LinearLayout(this);
- layout.setOrientation(LinearLayout.HORIZONTAL);
- final NumberPicker pickerWidth = new NumberPicker(this);
- pickerWidth.setMinValue(24);
- pickerWidth.setMaxValue(64);
- pickerWidth.setWrapSelectorWheel(false);
- pickerWidth.setValue(currentTileWidth);
- final NumberPicker pickerHeight = new NumberPicker(this);
- pickerHeight.setMinValue(24);
- pickerHeight.setMaxValue(64);
- pickerHeight.setWrapSelectorWheel(false);
- pickerHeight.setValue(currentTileHeight);
- layout.addView(pickerWidth);
- layout.addView(pickerHeight);
- new AlertDialog.Builder(this)
- .setView(layout)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(@NonNull DialogInterface dialog, int which) {
- currentTileWidth = pickerWidth.getValue();
- currentTileHeight = pickerHeight.getValue();
- widget.setTileSize(-1);
- widget.setTileWidthDp(currentTileWidth);
- widget.setTileHeightDp(currentTileHeight);
- }
- })
- .show();
- }
-
- @OnClick(R.id.button_clear_selection)
- void onClearSelection() {
- widget.clearSelection();
- }
-
- @OnClick(R.id.button_selection_mode)
- void onChangeSelectionMode() {
- CharSequence[] items = {
- "No Selection",
- "Single Date",
- "Multiple Dates",
- "Range of Dates"
- };
- new AlertDialog.Builder(this)
- .setTitle("Selection Mode")
- .setSingleChoiceItems(
- items,
- widget.getSelectionMode(),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- widget.setSelectionMode(which);
- dialog.dismiss();
- }
- }
- )
- .show();
- }
-
- @OnClick(R.id.button_change_orientation)
- void onButtonChangeOrientation() {
- widget.setTitleAnimationOrientation(
- widget.getTitleAnimationOrientation() == MaterialCalendarView.VERTICAL
- ? MaterialCalendarView.HORIZONTAL
- : MaterialCalendarView.VERTICAL);
-
- Toast.makeText(
- this,
- widget.getTitleAnimationOrientation() == MaterialCalendarView.VERTICAL
- ? "Vertical"
- : "Horizontal",
- Toast.LENGTH_SHORT
- ).show();
- }
-
- private static final DayOfWeek[] DAYS_OF_WEEK = {
- DayOfWeek.SUNDAY,
- DayOfWeek.MONDAY,
- DayOfWeek.TUESDAY,
- DayOfWeek.WEDNESDAY,
- DayOfWeek.THURSDAY,
- DayOfWeek.FRIDAY,
- DayOfWeek.SATURDAY,
- };
-
- @OnClick(R.id.button_set_first_day)
- void onFirstDayOfWeekClicked() {
- int index = random.nextInt(DAYS_OF_WEEK.length);
- widget.state().edit().setFirstDayOfWeek(DAYS_OF_WEEK[index]).commit();
- }
-
- @OnClick(R.id.button_weeks)
- public void onSetWeekMode() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && animateModeTransition.isChecked()) {
- TransitionManager.beginDelayedTransition(parent);
- }
- widget.state().edit().setCalendarDisplayMode(CalendarMode.WEEKS).commit();
- }
-
- @OnClick(R.id.button_months)
- public void onSetMonthMode() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && animateModeTransition.isChecked()) {
- TransitionManager.beginDelayedTransition(parent);
- }
- widget.state().edit().setCalendarDisplayMode(CalendarMode.MONTHS).commit();
- }
-
- public static void showDatePickerDialog(
- Context context, CalendarDay day,
- DatePickerDialog.OnDateSetListener callback) {
- if (day == null) {
- day = CalendarDay.today();
- }
- DatePickerDialog dialog = new DatePickerDialog(
- context, 0, callback, day.getYear(), day.getMonth() - 1, day.getDay()
- );
- dialog.show();
- }
-
- @Override
- public void onDateLongClick(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date) {
- Toast.makeText(this, FORMATTER.format(date.getDate()), Toast.LENGTH_SHORT).show();
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/GettersActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/GettersActivity.java
deleted file mode 100644
index 42d9bd96..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/GettersActivity.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.util.Log;
-import android.view.View;
-import android.widget.Toast;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnCheckedChanged;
-import butterknife.OnClick;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.CalendarMode;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import java.util.List;
-
-/**
- * Because the calendar has a lot of getters method, this activity is here to demonstrate what each
- * getter is returning. For more information, make sure to check the documentation.
- */
-public class GettersActivity extends AppCompatActivity {
- public static final CharSequence[] ITEMS =
- new CharSequence[] { "NONE", "SINGLE", "MULTIPLE", "RANGE" };
-
- @BindView(R.id.calendarView) MaterialCalendarView widget;
-
- @Override protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_getters);
- ButterKnife.bind(this);
- }
-
- @OnCheckedChanged(R.id.calendar_mode)
- void onCalendarModeChanged(boolean checked) {
- final CalendarMode mode = checked ? CalendarMode.WEEKS : CalendarMode.MONTHS;
- widget.state().edit().setCalendarDisplayMode(mode).commit();
- }
-
- @OnClick(R.id.button_selection_mode) void onChangeSelectionMode() {
- new AlertDialog.Builder(this)
- .setTitle("Selection Mode")
- .setSingleChoiceItems(ITEMS, widget.getSelectionMode(), (dialog, which) -> {
- widget.setSelectionMode(which);
- dialog.dismiss();
- })
- .show();
- }
-
- @OnClick(R.id.get_current_date) public void getCurrentDatesClick(final View v) {
- Toast.makeText(this, widget.getCurrentDate().toString(), Toast.LENGTH_SHORT).show();
- Log.e("GettersActivity", widget.getCurrentDate().toString());
- }
-
- @OnClick(R.id.get_selected_date) public void getSelectedDatesClick(final View v) {
- final CalendarDay selectedDate = widget.getSelectedDate();
- if (selectedDate != null) {
- Toast.makeText(this, selectedDate.toString(), Toast.LENGTH_SHORT).show();
- Log.e("GettersActivity", selectedDate.toString());
- } else {
- Toast.makeText(this, "No Selection", Toast.LENGTH_SHORT).show();
- }
- }
-
- @OnClick(R.id.get_selected_dates) public void getSelectedDateClick(final View v) {
- final List selectedDates = widget.getSelectedDates();
- if (!selectedDates.isEmpty()) {
- Toast.makeText(this, selectedDates.toString(), Toast.LENGTH_SHORT).show();
- Log.e("GettersActivity", selectedDates.toString());
- } else {
- Toast.makeText(this, "No Selection", Toast.LENGTH_SHORT).show();
- }
- }
-
- @OnClick(R.id.get_selection_mode) public void getSelectionModeClick(final View v) {
- Toast.makeText(this, ITEMS[widget.getSelectionMode()], Toast.LENGTH_SHORT).show();
- Log.e("GettersActivity", ITEMS[widget.getSelectionMode()].toString());
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MainActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MainActivity.java
deleted file mode 100644
index 4e8ecbd8..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MainActivity.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import java.util.List;
-
-/**
- * Routing Activity for other samples
- */
-public class MainActivity extends AppCompatActivity {
-
- private static final String CATEGORY_SAMPLE =
- "com.prolificinteractive.materialcalendarview.sample.SAMPLE";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- RecyclerView list = findViewById(R.id.list);
- list.setLayoutManager(new LinearLayoutManager(this));
- list.setAdapter(new ResolveInfoAdapter(this, getAllSampleActivities()));
- }
-
- private List getAllSampleActivities() {
- Intent filter = new Intent();
- filter.setAction(Intent.ACTION_RUN);
- filter.addCategory(CATEGORY_SAMPLE);
- return getPackageManager().queryIntentActivities(filter, 0);
- }
-
- private void onRouteClicked(ResolveInfo route) {
- ActivityInfo activity = route.activityInfo;
- ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
- startActivity(new Intent(Intent.ACTION_VIEW).setComponent(name));
- }
-
- class ResolveInfoAdapter extends RecyclerView.Adapter {
-
- private final PackageManager pm;
- private final LayoutInflater inflater;
- private final List samples;
-
- private ResolveInfoAdapter(Context context, List resolveInfos) {
- this.samples = resolveInfos;
- this.inflater = LayoutInflater.from(context);
- this.pm = context.getPackageManager();
- }
-
- @Override
- public ResolveInfoViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
- View view = inflater.inflate(R.layout.item_route, viewGroup, false);
- return new ResolveInfoViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(ResolveInfoViewHolder viewHolder, int i) {
- ResolveInfo item = samples.get(i);
- viewHolder.textView.setText(item.loadLabel(pm));
- }
-
- @Override
- public int getItemCount() {
- return samples.size();
- }
-
- class ResolveInfoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
-
- public final TextView textView;
-
- public ResolveInfoViewHolder(View view) {
- super(view);
- this.textView = view.findViewById(android.R.id.text1);
- view.setOnClickListener(this);
- }
-
- @Override
- public void onClick(@NonNull View v) {
- onRouteClicked(samples.get(getAdapterPosition()));
- }
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleSizeActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleSizeActivity.java
deleted file mode 100644
index 10cc9360..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleSizeActivity.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-
-/**
- * Displays various ways of sizing CalendarView
- */
-public class MultipleSizeActivity extends AppCompatActivity {
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_multiple_size);
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleViewActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleViewActivity.java
deleted file mode 100644
index a0066ffe..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/MultipleViewActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import org.threeten.bp.LocalDate;
-
-/**
- * In response to the issue comment at
- * https://github.com/prolificinteractive/material-calendarview/issues/8#issuecomment-241205704
- * , test activity with multiple MaterialCalendarViews
- */
-public class MultipleViewActivity extends AppCompatActivity {
- //number of MaterialCalendarViews to display in list
- static final int NUM_ENTRIES = 3;
-
- @BindView(R.id.calendar_list)
- RecyclerView calendarList;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_multiple);
- ButterKnife.bind(this);
-
- //setup RecyclerView
- calendarList.setLayoutManager(new LinearLayoutManager(this));
- calendarList.setAdapter(new MultipleViewAdapter(this));
- }
-
- /**
- * Adapter for RecyclerView
- */
- class MultipleViewAdapter extends RecyclerView.Adapter {
- final LayoutInflater inflater;
-
- MultipleViewAdapter(final Context context) {
- inflater = LayoutInflater.from(context);
- }
-
- @Override
- public EntryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- final View view = inflater.inflate(R.layout.calendar_list_entry, parent, false);
- return new EntryViewHolder(view);
- }
-
- @Override
- public int getItemCount() {
- return NUM_ENTRIES;
- }
-
- @Override
- public void onBindViewHolder(EntryViewHolder holder, int position) {
- //set selected date to today
- holder.calendarView.setSelectedDate(LocalDate.now());
- }
-
- /**
- * View holder for list entry
- */
- class EntryViewHolder extends RecyclerView.ViewHolder {
- final MaterialCalendarView calendarView;
-
- EntryViewHolder(final View itemView) {
- super(itemView);
- calendarView = itemView.findViewById(R.id.list_entry);
- }
- }
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/OldCalendarViewActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/OldCalendarViewActivity.java
deleted file mode 100644
index aabd146d..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/OldCalendarViewActivity.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.widget.CalendarView;
-import android.widget.TextView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-
-/**
- * Shows off the most basic usage
- */
-public class OldCalendarViewActivity extends AppCompatActivity
- implements CalendarView.OnDateChangeListener {
-
- private static final DateFormat FORMATTER = SimpleDateFormat.getDateInstance();
-
- @BindView(R.id.calendarView)
- CalendarView widget;
-
- @BindView(R.id.textView)
- TextView textView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_old_calendarview);
- ButterKnife.bind(this);
-
- widget.setOnDateChangeListener(this);
- }
-
- @Override
- public void onSelectedDayChange(
- CalendarView view, int year, int month,
- int dayOfMonth) {
- textView.setText(FORMATTER.format(view.getDate()));
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/RotationActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/RotationActivity.java
deleted file mode 100644
index 1db75395..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/RotationActivity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import android.widget.Toast;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateLongClickListener;
-import com.prolificinteractive.materialcalendarview.OnMonthChangedListener;
-import org.threeten.bp.format.DateTimeFormatter;
-
-/**
- * Shows off the most basic usage
- */
-public class RotationActivity extends AppCompatActivity
- implements OnMonthChangedListener, OnDateLongClickListener {
-
- private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, d MMM yyyy");
-
- @BindView(R.id.calendarView)
- MaterialCalendarView widget;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_rotation);
- ButterKnife.bind(this);
-
- widget.setOnDateLongClickListener(this);
- widget.setOnMonthChangedListener(this);
- }
-
- @Override
- public void onDateLongClick(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date) {
- final String text = String.format("%s is available", FORMATTER.format(date.getDate()));
- Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
- //noinspection ConstantConditions
- getSupportActionBar().setTitle(FORMATTER.format(date.getDate()));
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SelectionModesActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SelectionModesActivity.java
deleted file mode 100644
index 45135558..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SelectionModesActivity.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import android.transition.TransitionManager;
-import android.view.ViewGroup;
-import android.widget.Toast;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnCheckedChanged;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.CalendarMode;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
-import com.prolificinteractive.materialcalendarview.OnRangeSelectedListener;
-import com.prolificinteractive.materialcalendarview.sample.decorators.RangeDayDecorator;
-import java.util.List;
-import org.threeten.bp.format.DateTimeFormatter;
-
-/**
- * An activity that demonstrate the multiple selection mode that the calendar offers.
- * The mode can be set through xml or in java.
- *
- * @see MaterialCalendarView.SelectionMode
- */
-public class SelectionModesActivity extends AppCompatActivity
- implements OnDateSelectedListener, OnRangeSelectedListener {
-
- private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, d MMM yyyy");
-
- @BindView(R.id.parent) ViewGroup parent;
- @BindView(R.id.calendar_view_single) MaterialCalendarView single;
- @BindView(R.id.calendar_view_multi) MaterialCalendarView multi;
- @BindView(R.id.calendar_view_range) MaterialCalendarView range;
- @BindView(R.id.calendar_view_none) MaterialCalendarView none;
-
- private RangeDayDecorator decorator;
-
- @Override protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_selection_modes);
- ButterKnife.bind(this);
-
- decorator = new RangeDayDecorator(this);
-
- single.setOnDateChangedListener(this);
- multi.setOnDateChangedListener(this);
- range.setOnDateChangedListener(this);
- range.setOnRangeSelectedListener(this);
- range.addDecorator(decorator);
- none.setOnDateChangedListener(this);
- }
-
- @Override public void onDateSelected(
- @NonNull final MaterialCalendarView widget,
- @NonNull final CalendarDay date,
- final boolean selected) {
- final String text = selected ? FORMATTER.format(date.getDate()) : "No Selection";
- Toast.makeText(SelectionModesActivity.this, text, Toast.LENGTH_SHORT).show();
- }
-
- @Override public void onRangeSelected(
- @NonNull final MaterialCalendarView widget,
- @NonNull final List dates) {
- if (dates.size() > 0) {
- decorator.addFirstAndLast(dates.get(0), dates.get(dates.size() - 1));
- range.invalidateDecorators();
- }
- }
-
- @OnCheckedChanged(R.id.calendar_mode)
- void onCalendarModeChanged(boolean checked) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- TransitionManager.beginDelayedTransition(parent);
- }
- final CalendarMode mode = checked ? CalendarMode.WEEKS : CalendarMode.MONTHS;
- single.state().edit().setCalendarDisplayMode(mode).commit();
- multi.state().edit().setCalendarDisplayMode(mode).commit();
- range.state().edit().setCalendarDisplayMode(mode).commit();
- none.state().edit().setCalendarDisplayMode(mode).commit();
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java
deleted file mode 100644
index aaa5ba6f..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample;
-
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.CalendarMode;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.OnDateSelectedListener;
-import com.prolificinteractive.materialcalendarview.sample.decorators.HighlightWeekendsDecorator;
-import com.prolificinteractive.materialcalendarview.sample.decorators.MySelectorDecorator;
-import com.prolificinteractive.materialcalendarview.sample.decorators.OneDayDecorator;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.Month;
-
-/**
- * Shows off the most basic usage
- */
-public class SwappableBasicActivityDecorated extends AppCompatActivity
- implements OnDateSelectedListener {
-
- private final OneDayDecorator oneDayDecorator = new OneDayDecorator();
-
- @BindView(R.id.calendarView) MaterialCalendarView widget;
-
- @Override protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_basic_modes);
- ButterKnife.bind(this);
-
- widget.setOnDateChangedListener(this);
- widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL);
-
- final LocalDate instance = LocalDate.now();
- widget.setSelectedDate(instance);
-
- final LocalDate min = LocalDate.of(instance.getYear(), Month.JANUARY, 1);
- final LocalDate max = LocalDate.of(instance.getYear(), Month.DECEMBER, 31);
-
- widget.state().edit().setMinimumDate(min).setMaximumDate(max).commit();
-
- widget.addDecorators(
- new MySelectorDecorator(this),
- new HighlightWeekendsDecorator(),
- oneDayDecorator
- );
- }
-
- @Override
- public void onDateSelected(
- @NonNull MaterialCalendarView widget,
- @NonNull CalendarDay date,
- boolean selected) {
- //If you change a decorate, you need to invalidate decorators
- oneDayDecorator.setDate(date.getDate());
- widget.invalidateDecorators();
- }
-
- @OnClick(R.id.button_weeks)
- public void onSetWeekMode() {
- widget.state().edit()
- .setCalendarDisplayMode(CalendarMode.WEEKS)
- .commit();
- }
-
- @OnClick(R.id.button_months)
- public void onSetMonthMode() {
- widget.state().edit()
- .setCalendarDisplayMode(CalendarMode.MONTHS)
- .commit();
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/EventDecorator.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/EventDecorator.java
deleted file mode 100644
index 95079557..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/EventDecorator.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample.decorators;
-
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.spans.DotSpan;
-import java.util.Collection;
-import java.util.HashSet;
-
-/**
- * Decorate several days with a dot
- */
-public class EventDecorator implements DayViewDecorator {
-
- private int color;
- private HashSet dates;
-
- public EventDecorator(int color, Collection dates) {
- this.color = color;
- this.dates = new HashSet<>(dates);
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return dates.contains(day);
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.addSpan(new DotSpan(5, color));
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/HighlightWeekendsDecorator.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/HighlightWeekendsDecorator.java
deleted file mode 100644
index 22e5b500..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/HighlightWeekendsDecorator.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample.decorators;
-
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import org.threeten.bp.DayOfWeek;
-
-/**
- * Highlight Saturdays and Sundays with a background
- */
-public class HighlightWeekendsDecorator implements DayViewDecorator {
-
- private final Drawable highlightDrawable;
- private static final int color = Color.parseColor("#228BC34A");
-
- public HighlightWeekendsDecorator() {
- highlightDrawable = new ColorDrawable(color);
- }
-
- @Override public boolean shouldDecorate(final CalendarDay day) {
- final DayOfWeek weekDay = day.getDate().getDayOfWeek();
- return weekDay == DayOfWeek.SATURDAY || weekDay == DayOfWeek.SUNDAY;
- }
-
- @Override public void decorate(final DayViewFacade view) {
- view.setBackgroundDrawable(highlightDrawable);
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/MySelectorDecorator.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/MySelectorDecorator.java
deleted file mode 100644
index f35b3bcc..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/MySelectorDecorator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample.decorators;
-
-import android.app.Activity;
-import android.graphics.drawable.Drawable;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.sample.R;
-
-/**
- * Use a custom selector
- */
-public class MySelectorDecorator implements DayViewDecorator {
-
- private final Drawable drawable;
-
- public MySelectorDecorator(Activity context) {
- drawable = context.getResources().getDrawable(R.drawable.my_selector);
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return true;
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.setSelectionDrawable(drawable);
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/OneDayDecorator.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/OneDayDecorator.java
deleted file mode 100644
index e6735f4b..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/OneDayDecorator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample.decorators;
-
-import android.graphics.Typeface;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.StyleSpan;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import org.threeten.bp.LocalDate;
-
-/**
- * Decorate a day by making the text big and bold
- */
-public class OneDayDecorator implements DayViewDecorator {
-
- private CalendarDay date;
-
- public OneDayDecorator() {
- date = CalendarDay.today();
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return date != null && day.equals(date);
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.addSpan(new StyleSpan(Typeface.BOLD));
- view.addSpan(new RelativeSizeSpan(1.4f));
- }
-
- /**
- * We're changing the internals, so make sure to call {@linkplain MaterialCalendarView#invalidateDecorators()}
- */
- public void setDate(LocalDate date) {
- this.date = CalendarDay.from(date);
- }
-}
diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/RangeDayDecorator.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/RangeDayDecorator.java
deleted file mode 100644
index dfe3dd7f..00000000
--- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/decorators/RangeDayDecorator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.prolificinteractive.materialcalendarview.sample.decorators;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import com.prolificinteractive.materialcalendarview.CalendarDay;
-import com.prolificinteractive.materialcalendarview.DayViewDecorator;
-import com.prolificinteractive.materialcalendarview.DayViewFacade;
-import com.prolificinteractive.materialcalendarview.MaterialCalendarView;
-import com.prolificinteractive.materialcalendarview.sample.R;
-import java.util.HashSet;
-
-/**
- * Decorate 2 days.
- */
-public class RangeDayDecorator implements DayViewDecorator {
-
- private final HashSet list = new HashSet<>();
- private final Drawable drawable;
-
- public RangeDayDecorator(final Context context) {
- drawable = context.getResources().getDrawable(R.drawable.my_selector);
- }
-
- @Override
- public boolean shouldDecorate(CalendarDay day) {
- return list.contains(day);
- }
-
- @Override
- public void decorate(DayViewFacade view) {
- view.setSelectionDrawable(drawable);
- }
-
- /**
- * We're changing the dates, so make sure to call {@linkplain MaterialCalendarView#invalidateDecorators()}
- */
- public void addFirstAndLast(final CalendarDay first, final CalendarDay last) {
- list.clear();
- list.add(first);
- list.add(last);
- }
-}
diff --git a/sample/src/main/res/drawable-hdpi/ic_my_selector.png b/sample/src/main/res/drawable-hdpi/ic_my_selector.png
deleted file mode 100644
index 46ceaba6..00000000
Binary files a/sample/src/main/res/drawable-hdpi/ic_my_selector.png and /dev/null differ
diff --git a/sample/src/main/res/drawable-mdpi/ic_my_selector.png b/sample/src/main/res/drawable-mdpi/ic_my_selector.png
deleted file mode 100644
index 3b48334b..00000000
Binary files a/sample/src/main/res/drawable-mdpi/ic_my_selector.png and /dev/null differ
diff --git a/sample/src/main/res/drawable-xhdpi/ic_my_selector.png b/sample/src/main/res/drawable-xhdpi/ic_my_selector.png
deleted file mode 100644
index 4010b796..00000000
Binary files a/sample/src/main/res/drawable-xhdpi/ic_my_selector.png and /dev/null differ
diff --git a/sample/src/main/res/drawable-xxhdpi/ic_my_selector.png b/sample/src/main/res/drawable-xxhdpi/ic_my_selector.png
deleted file mode 100644
index 3b531e9c..00000000
Binary files a/sample/src/main/res/drawable-xxhdpi/ic_my_selector.png and /dev/null differ
diff --git a/sample/src/main/res/drawable/ic_arrow_back.xml b/sample/src/main/res/drawable/ic_arrow_back.xml
deleted file mode 100644
index 031f901d..00000000
--- a/sample/src/main/res/drawable/ic_arrow_back.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
diff --git a/sample/src/main/res/drawable/ic_arrow_forward.xml b/sample/src/main/res/drawable/ic_arrow_forward.xml
deleted file mode 100644
index 60f93ad7..00000000
--- a/sample/src/main/res/drawable/ic_arrow_forward.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
diff --git a/sample/src/main/res/drawable/my_selector.xml b/sample/src/main/res/drawable/my_selector.xml
deleted file mode 100644
index 8d839141..00000000
--- a/sample/src/main/res/drawable/my_selector.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/drawable/today_circle_background.xml b/sample/src/main/res/drawable/today_circle_background.xml
deleted file mode 100644
index 953e4714..00000000
--- a/sample/src/main/res/drawable/today_circle_background.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/font/shirkhand.xml b/sample/src/main/res/font/shirkhand.xml
deleted file mode 100644
index a1dc4760..00000000
--- a/sample/src/main/res/font/shirkhand.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/font/shrikhand_regular.ttf b/sample/src/main/res/font/shrikhand_regular.ttf
deleted file mode 100755
index e52b55e4..00000000
Binary files a/sample/src/main/res/font/shrikhand_regular.ttf and /dev/null differ
diff --git a/sample/src/main/res/layout-land/activity_rotation.xml b/sample/src/main/res/layout-land/activity_rotation.xml
deleted file mode 100644
index f55f2495..00000000
--- a/sample/src/main/res/layout-land/activity_rotation.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_basic.xml b/sample/src/main/res/layout/activity_basic.xml
deleted file mode 100644
index c71b8736..00000000
--- a/sample/src/main/res/layout/activity_basic.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_basic_modes.xml b/sample/src/main/res/layout/activity_basic_modes.xml
deleted file mode 100644
index 43b86338..00000000
--- a/sample/src/main/res/layout/activity_basic_modes.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_custom_tile.xml b/sample/src/main/res/layout/activity_custom_tile.xml
deleted file mode 100644
index d50df19d..00000000
--- a/sample/src/main/res/layout/activity_custom_tile.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_customization.xml b/sample/src/main/res/layout/activity_customization.xml
deleted file mode 100644
index 9cb5d91a..00000000
--- a/sample/src/main/res/layout/activity_customization.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
diff --git a/sample/src/main/res/layout/activity_dialogs.xml b/sample/src/main/res/layout/activity_dialogs.xml
deleted file mode 100644
index 4b4abbb7..00000000
--- a/sample/src/main/res/layout/activity_dialogs.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_dynamic_setters.xml b/sample/src/main/res/layout/activity_dynamic_setters.xml
deleted file mode 100644
index ff6f84ae..00000000
--- a/sample/src/main/res/layout/activity_dynamic_setters.xml
+++ /dev/null
@@ -1,270 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_getters.xml b/sample/src/main/res/layout/activity_getters.xml
deleted file mode 100644
index 06fdbe73..00000000
--- a/sample/src/main/res/layout/activity_getters.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
deleted file mode 100644
index a0b43f99..00000000
--- a/sample/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/sample/src/main/res/layout/activity_multiple.xml b/sample/src/main/res/layout/activity_multiple.xml
deleted file mode 100644
index a303ae00..00000000
--- a/sample/src/main/res/layout/activity_multiple.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
diff --git a/sample/src/main/res/layout/activity_multiple_size.xml b/sample/src/main/res/layout/activity_multiple_size.xml
deleted file mode 100644
index 9bf38d60..00000000
--- a/sample/src/main/res/layout/activity_multiple_size.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_old_calendarview.xml b/sample/src/main/res/layout/activity_old_calendarview.xml
deleted file mode 100644
index addbb6bc..00000000
--- a/sample/src/main/res/layout/activity_old_calendarview.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_rotation.xml b/sample/src/main/res/layout/activity_rotation.xml
deleted file mode 100644
index 038132c4..00000000
--- a/sample/src/main/res/layout/activity_rotation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/activity_selection_modes.xml b/sample/src/main/res/layout/activity_selection_modes.xml
deleted file mode 100644
index 266e75dc..00000000
--- a/sample/src/main/res/layout/activity_selection_modes.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/calendar_list_entry.xml b/sample/src/main/res/layout/calendar_list_entry.xml
deleted file mode 100644
index d1ce8647..00000000
--- a/sample/src/main/res/layout/calendar_list_entry.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/dialog_basic.xml b/sample/src/main/res/layout/dialog_basic.xml
deleted file mode 100644
index 697fda6c..00000000
--- a/sample/src/main/res/layout/dialog_basic.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/layout/item_route.xml b/sample/src/main/res/layout/item_route.xml
deleted file mode 100644
index 109d1273..00000000
--- a/sample/src/main/res/layout/item_route.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
\ No newline at end of file
diff --git a/sample/src/main/res/menu/menu_main.xml b/sample/src/main/res/menu/menu_main.xml
deleted file mode 100644
index 947d5c6d..00000000
--- a/sample/src/main/res/menu/menu_main.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 12f0544a..00000000
Binary files a/sample/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 55efdd0e..00000000
Binary files a/sample/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index e9c8bb21..00000000
Binary files a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 853b9814..00000000
Binary files a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 186f6801..00000000
Binary files a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/src/main/res/values/colors.xml b/sample/src/main/res/values/colors.xml
deleted file mode 100644
index b8eb3f7f..00000000
--- a/sample/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- #0093FF
- #006BBA
-
\ No newline at end of file
diff --git a/sample/src/main/res/values/dimens.xml b/sample/src/main/res/values/dimens.xml
deleted file mode 100644
index 8db086eb..00000000
--- a/sample/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
- 16dp
- 16dp
-
- 100dp
- 32dp
- 16dp
-
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
deleted file mode 100644
index 14c104be..00000000
--- a/sample/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
- Material CalendarView Samples
- Hello world!
- Settings
- Basic Example
- Disabled Days Example
- XML Customization Example
- Programmatic Customization Example
- Dynamic Setters Test
- Custom tile width/height
- Old CalendarView
- Calendar in Dialogs
- Calendar with Decorators
- Calendar with Getters
- Rotation Example
- Calendar Selection Modes
- Calendar with Dynamic Modes
- Multiple Basic Calendars
- Many-Sized Calendars
-
-
- M
- Tu
- W
- Th
- F
- Sa
- Su
-
-
-
- JAN
- Feb
- MARCH
- April
- MAY
- June
- JULY
- Aug
- SEPT
- Oct
- Nov
- DEC
-
-
- Fitted for screen (common use)
- Fitted for small layout parameters
- Tile size specified
- Tile width and height specified (thin)
- Tile width and height specified (wide)
-
-
- Today is the day
-
diff --git a/sample/src/main/res/values/styles.xml b/sample/src/main/res/values/styles.xml
deleted file mode 100644
index 154fae47..00000000
--- a/sample/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/settings.gradle b/settings.gradle
index 77c36d03..d8f14a13 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':library', ':sample'
+include ':library'