From 374abd3eeb78d27c9ccfaa6d96347aeea21d361f Mon Sep 17 00:00:00 2001 From: sasa_droidgreen Date: Thu, 7 Apr 2016 11:36:29 +0100 Subject: [PATCH 1/2] Feature: Display events, display badges on events, date picker scroll orientation Added new classes: Badge, CalendarwBadge, Events, DatePicker, DayPickerViewInterface, DayPickerRecyclerView, MonthRecyclerViewAdapter --- README.md | 16 +- library/build.gradle | 6 +- library/src/main/AndroidManifest.xml | 5 + .../materialdatetimepicker/date/Badge.java | 72 ++++ .../date/CalendarwBadge.java | 65 ++++ .../date/DatePicker.java | 39 ++ .../date/DatePickerController.java | 8 + .../date/DatePickerDialog.java | 113 +++++- .../date/DayPickerRecyclerView.java | 337 ++++++++++++++++++ .../date/DayPickerView.java | 2 +- .../date/DayPickerViewInterface.java | 11 + .../materialdatetimepicker/date/Events.java | 63 ++++ .../date/MonthAdapter.java | 4 +- .../date/MonthRecyclerViewAdapter.java | 125 +++++++ .../date/MonthView.java | 62 +++- .../date/SimpleMonthView.java | 5 + library/src/main/res/values/dimens.xml | 2 + 17 files changed, 917 insertions(+), 18 deletions(-) create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/Badge.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/CalendarwBadge.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePicker.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerRecyclerView.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerViewInterface.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/Events.java create mode 100644 library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthRecyclerViewAdapter.java diff --git a/README.md b/README.md index 12b6191b..3c515a0a 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,18 @@ dpd.show(getFragmentManager(), "Datepickerdialog"); ``` ### Theme the pickers -The pickers will be themed automatically based on the current theme where they are created, based on the current `colorAccent`. You can also theme the dialogs via the `setAccentColor(int color)` method. Alternatively, you can theme the pickers by overwriting the color resources `mdtp_accent_color` and `mdtp_accent_color_dark` in your project. +The pickers will be themed automatically based on the current theme where they are created, based on the current `colorAccent`. You can also theme the dialogs via the `setAccentColor(int eventColor)` method. Alternatively, you can theme the pickers by overwriting the eventColor resources `mdtp_accent_color` and `mdtp_accent_color_dark` in your project. ```xml -#009688 -#00796b +#009688 +#00796b ``` The exact order in which colors are selected is as follows: -1. `setAccentColor(int color)` in java code +1. `setAccentColor(int eventColor)` in java code 2. `android.R.attr.colorAccent` (if android 5.0+) 3. `R.attr.colorAccent` (eg. when using AppCompat) -4. `R.color.mdtp_accent_color` and `R.color.mdtp_accent_color_dark` if none of the others are set in your project +4. `R.eventColor.mdtp_accent_color` and `R.eventColor.mdtp_accent_color_dark` if none of the others are set in your project The pickers also have a dark theme. This can be specified globablly using the `mdtp_theme_dark` attribute in your theme or the `setThemeDark(boolean themeDark)` functions. The function calls overwrite the XML setting. ```xml @@ -111,8 +111,8 @@ The `DatePickerDialog` has a dark theme that can be set by calling dpd.setThemeDark(true); ``` -* `setAccentColor(String color)` and `setAccentColor(int color)` -Set the accentColor to be used by the Dialog. The String version parses the color out using `Color.parseColor()`. The int version requires a ColorInt bytestring. It will explicitly set the color to fully opaque. +* `setAccentColor(String eventColor)` and `setAccentColor(int eventColor)` +Set the accentColor to be used by the Dialog. The String version parses the eventColor out using `Color.parseColor()`. The int version requires a ColorInt bytestring. It will explicitly set the eventColor to fully opaque. * `TimePickerDialog` `setTitle(String title)` Shows a title at the top of the `TimePickerDialog` @@ -139,7 +139,7 @@ Set the interval for selectable times in the TimePickerDialog. This is a conveni You can pass a `Calendar[]` to the `DatePickerDialog`. The values in this list are the only acceptable dates for the picker. It takes precedence over `setMinDate(Calendar day)` and `setMaxDate(Calendar day)` * `setHighlightedDays(Calendar[] days)` -You can pass a `Calendar[]` of days to highlight. They will be rendered in bold. You can tweak the color of the highlighted days by overwriting `mdtp_date_picker_text_highlighted` +You can pass a `Calendar[]` of days to highlight. They will be rendered in bold. You can tweak the eventColor of the highlighted days by overwriting `mdtp_date_picker_text_highlighted` * `showYearPickerFirst(boolean yearPicker)` Show the year picker first, rather than the month and day picker. diff --git a/library/build.gradle b/library/build.gradle index d7bfb225..a1c8328d 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -16,11 +16,15 @@ android { minifyEnabled false } } + productFlavors { + } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:23.1.1' + compile 'com.android.support:recyclerview-v7:23.2.1' + compile 'com.android.support:design:23.2.1' } -apply from: 'gradle-mvn-push.gradle' \ No newline at end of file +apply from: 'gradle-mvn-push.gradle' diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index c2ef964e..6b7f225a 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -18,5 +18,10 @@ + + + + + diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Badge.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Badge.java new file mode 100644 index 00000000..64da696b --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Badge.java @@ -0,0 +1,72 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.os.Parcel; +import android.os.Parcelable; + +public class Badge implements Parcelable { + public static final int TOP_RIGHT = 1; + public static final int TOP_LEFT = 2; + public static final int BOTTOM_RIGHT = 3; + public static final int BOTTOM_LEFT = 4; + + private int location = TOP_LEFT; + private int color = -1; + private int displayInt = 0; + + public Badge(int displayInt){ + this.displayInt = displayInt; + } + + public int getLocation() { + return location; + } + + public void setLocation(int location) { + this.location = location; + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + + public int getDisplayInt() { + return displayInt; + } + + public void setDisplayInt(int displayInt) { + this.displayInt = displayInt; + } + + //parcelling part + public Badge(Parcel in){ + location = in.readInt(); + color = in.readInt(); + displayInt = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(location); + dest.writeInt(color); + dest.writeInt(displayInt); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Badge createFromParcel(Parcel in) { + return new Badge(in); + } + + public Badge[] newArray(int size) { + return new Badge[size]; + } + }; +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/CalendarwBadge.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/CalendarwBadge.java new file mode 100644 index 00000000..69fcee92 --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/CalendarwBadge.java @@ -0,0 +1,65 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.Calendar; + +public class CalendarwBadge extends MonthAdapter.CalendarDay implements Parcelable{ + private ArrayList badgeArrayList; + + public CalendarwBadge() {super();} + + public CalendarwBadge(long timeInMillis) {super(timeInMillis);} + + public CalendarwBadge(Calendar calendar) {super(calendar);} + + public CalendarwBadge(int year, int month, int day) { + super(year, month, day); + } + + public ArrayList getBadgeArrayList() { + return badgeArrayList; + } + + /** + * Set list of badges to be displayed. + * + * @param badgeArrayList List of badges. Maximum number of badges are 4. + */ + public void setBadgeArrayList(ArrayList badgeArrayList) { + this.badgeArrayList = badgeArrayList; + } + + //parcelling part + public CalendarwBadge(Parcel in){ + year = in.readInt(); + month = in.readInt(); + day = in.readInt(); + in.readTypedList(badgeArrayList, Badge.CREATOR); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(year); + dest.writeInt(month); + dest.writeInt(day); + dest.writeTypedList(badgeArrayList); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public CalendarwBadge createFromParcel(Parcel in) { + return new CalendarwBadge(in); + } + + public CalendarwBadge[] newArray(int size) { + return new CalendarwBadge[size]; + } + }; +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePicker.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePicker.java new file mode 100644 index 00000000..dc0f73ef --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePicker.java @@ -0,0 +1,39 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.app.FragmentManager; +import android.os.Build; + +import java.util.Calendar; + +public class DatePicker { + + /** + * Determine appropriate picker dialog to be shown + * Option for horizontal scroll only available for Android API >=7 + * + * @param manager Fragment manager of activity where picker dialog will be shown. + * @param events Contain details of events to be / not displayed on picker dialog. + * Pass null if there is no events to be displayed. + * @param tag Picker dialog's tag. + * @param scrollDirection Determine picker dialog scroll direction, + * use LinearLayoutManager.VERTICAL or LinearLayoutManager.HORIZONTAL, + * by default, it is LinearLayoutManager.VERTICAL. + */ + public static void displayDialog(FragmentManager manager, String tag, DatePickerDialog.OnDateSetListener listener, + Events events, int scrollDirection){ + + Calendar cal = Calendar.getInstance(); + DatePickerDialog datePickerFragment; + + if(Build.VERSION.SDK_INT >= 7){ + datePickerFragment = DatePickerDialog.newInstance(listener, cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), events, scrollDirection); + }else{ + if (events!=null) datePickerFragment = DatePickerDialog.newInstance (listener,cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),events); + else datePickerFragment = DatePickerDialog.newInstance (listener,cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + } + datePickerFragment.show(manager, tag); + } +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerController.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerController.java index 3ac4291a..682d8b42 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerController.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerController.java @@ -54,4 +54,12 @@ public interface DatePickerController { boolean isOutOfRange(int year, int month, int day); void tryVibrate(); + + //EVENTS + //--------------------------------------------------------------------- + boolean isEvent(int year, int month, int day); + int getEventColor(); + boolean isEventClickable(); + CalendarwBadge getCalendarwBadge(); + //--------------------------------------------------------------------- } diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java index 19b90d69..6cc72196 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DatePickerDialog.java @@ -23,11 +23,13 @@ import android.content.DialogInterface; import android.content.res.Resources; import android.graphics.Color; +import android.os.Build; import android.os.Bundle; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; +import android.support.v7.widget.LinearLayoutManager; import android.text.format.DateUtils; import android.util.Log; import android.view.LayoutInflater; @@ -48,11 +50,13 @@ import com.wdullaer.materialdatetimepicker.Utils; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashSet; import java.util.Locale; + /** * Dialog allowing users to select a date. */ @@ -114,7 +118,7 @@ public class DatePickerDialog extends DialogFragment implements private TextView mSelectedMonthTextView; private TextView mSelectedDayTextView; private TextView mYearView; - private DayPickerView mDayPickerView; + //private DayPickerView mDayPickerView; private YearPickerView mYearPickerView; private int mCurrentView = UNINITIALIZED; @@ -149,6 +153,14 @@ public class DatePickerDialog extends DialogFragment implements private String mYearPickerDescription; private String mSelectYear; + private static final String KEY_SCROLL_DIRECTION = "scroll_direction"; + private static final String KEY_EVENTS = "events"; + + private Events mEvents; + private DayPickerViewInterface mDayPickerView; + private int mScrollDirection = -1; + private CalendarwBadge mCalendarwBadge; + /** * The callback used to indicate the user is done filling in the date. */ @@ -172,12 +184,13 @@ public interface OnDateChangedListener { void onDateChanged(); } - public DatePickerDialog() { // Empty constructor required for dialog fragment. } /** + * Initializer for dialog without displaying events. + * * @param callBack How the parent is notified that the date is set. * @param year The initial year of the dialog. * @param monthOfYear The initial month of the dialog. @@ -198,6 +211,43 @@ public void initialize(OnDateSetListener callBack, int year, int monthOfYear, in mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); } + /** + * Initializer for dialog with option to display events. + * + * @param events Contain details of events to be / not displayed on picker dialog. + */ + public static DatePickerDialog newInstance(OnDateSetListener callBack, int year, + int monthOfYear, + int dayOfMonth, Events events) { + DatePickerDialog ret = new DatePickerDialog(); + ret.initialize(callBack, year, monthOfYear, dayOfMonth); + ret.initialize(events, -1); + return ret; + } + + /** + * Only available for Android API >=7. + * Initializer for dialog with option to display events + * and scroll orientation. + * + * @param events Contain details of events to be / not displayed on picker dialog. + * @param scrollDirection scrollDirection Determine picker dialog scroll direction, + * use LinearLayoutManager.VERTICAL or LinearLayoutManager.HORIZONTAL, + * by default, it is LinearLayoutManager.VERTICAL. + */ + public static DatePickerDialog newInstance(OnDateSetListener callBack, int year, int monthOfYear, + int dayOfMonth,Events events, int scrollDirection) { + DatePickerDialog ret = new DatePickerDialog(); + ret.initialize(callBack, year, monthOfYear, dayOfMonth); + ret.initialize(events, scrollDirection); + return ret; + } + + public void initialize(Events events, int scrollDirection){ + this.mEvents = events; + this.mScrollDirection = scrollDirection; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -247,6 +297,8 @@ public void onSaveInstanceState(@NonNull Bundle outState) { outState.putString(KEY_OK_STRING, mOkString); outState.putInt(KEY_CANCEL_RESID, mCancelResid); outState.putString(KEY_CANCEL_STRING, mCancelString); + outState.putInt(KEY_SCROLL_DIRECTION, mScrollDirection); + outState.putParcelable(KEY_EVENTS, mEvents); } @Override @@ -292,10 +344,14 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mOkString = savedInstanceState.getString(KEY_OK_STRING); mCancelResid = savedInstanceState.getInt(KEY_CANCEL_RESID); mCancelString = savedInstanceState.getString(KEY_CANCEL_STRING); + mScrollDirection = savedInstanceState.getInt(KEY_SCROLL_DIRECTION); + mEvents = savedInstanceState.getParcelable(KEY_EVENTS); } final Activity activity = getActivity(); - mDayPickerView = new SimpleDayPickerView(activity, this); + if(Build.VERSION.SDK_INT >= 7) + mDayPickerView = new DayPickerRecyclerView(activity, this, mScrollDirection); + else mDayPickerView = new SimpleDayPickerView(activity, this); mYearPickerView = new YearPickerView(activity, this); // if theme mode has not been set by java code, check if it is specified in Style.xml @@ -313,8 +369,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, view.setBackgroundColor(ContextCompat.getColor(activity, bgColorResource)); mAnimator = (AccessibleDateAnimator) view.findViewById(R.id.animator); - mAnimator.addView(mDayPickerView); + if(Build.VERSION.SDK_INT >= 7) + mAnimator.addView((DayPickerRecyclerView)mDayPickerView); + else mAnimator.addView((DayPickerView)mDayPickerView); mAnimator.addView(mYearPickerView); + mAnimator.setDateMillis(mCalendar.getTimeInMillis()); // TODO: Replace with animation decided upon by the design team. Animation animation = new AlphaAnimation(0.0f, 1.0f); @@ -547,7 +606,7 @@ public void setAccentColor(String color) { * @param color the accent color you want */ public void setAccentColor(@ColorInt int color) { - mAccentColor = Color.argb(255, Color.red(color), Color.green(color), Color.blue(color));; + mAccentColor = Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)); } /** @@ -987,4 +1046,48 @@ public void notifyOnDateListener() { mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH)); } } + + /** + * Check if the specified date (input parameters - year, month, day) is + * a date for an event. + */ + @Override + public boolean isEvent(int year, int month, int day) { + boolean hol = false; + + if (mEvents!=null){ + ArrayList calList = mEvents.getCalList(); + for(CalendarwBadge calendar:calList){ + if(calendar.getYear()==year){ + if(calendar.getMonth()== month){ + if(calendar.getDay()== day) { + hol = true; + mCalendarwBadge = calendar; + } + } + } + } + } + + return hol; + } + + @Override + public CalendarwBadge getCalendarwBadge() { + return mCalendarwBadge; + } + + @Override + public int getEventColor() { + if (mEvents!=null) + return mEvents.getEventColor(); + else return -1; + } + + @Override + public boolean isEventClickable() { + if (mEvents!=null) + return mEvents.isClickable(); + else return false; + } } diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerRecyclerView.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerRecyclerView.java new file mode 100644 index 00000000..3ae9e63f --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerRecyclerView.java @@ -0,0 +1,337 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.content.Context; +import android.os.Handler; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog.OnDateChangedListener; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + +public class DayPickerRecyclerView extends RecyclerView implements DayPickerViewInterface, OnDateChangedListener{ + + private static final String TAG = "MonthFragment"; + + protected static final int SCROLL_HYST_WEEKS = 2; // Affects when the month selection will change while scrolling up + protected static final int GOTO_SCROLL_DURATION = 250; // How long the GoTo fling animation should las + protected static final int SCROLL_CHANGE_DELAY = 40; // How long to wait after receiving an onScrollStateChanged notification before acting on it + public static final int DAYS_PER_WEEK = 7; // The number of days to display in each week + public static int LIST_TOP_OFFSET = -1; // so that the top line will be under the separator + + // You can override these numbers to get a different appearance + protected int mNumWeeks = 6; + protected boolean mShowWeekNumber = false; + protected int mDaysPerWeek = 7; + private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy", Locale.getDefault()); + protected float mFriction = 1.0f; // These affect the scroll speed and feel + + protected Context mContext; + protected Handler mHandler; + + // highlighted time + protected MonthAdapter.CalendarDay mSelectedDay = new MonthAdapter.CalendarDay(); + protected MonthRecyclerViewAdapter mAdapter; + protected MonthAdapter.CalendarDay mTempDay = new MonthAdapter.CalendarDay(); + + protected int mFirstDayOfWeek; // When the week starts; numbered like Time. (e.g. SUNDAY=0). + protected CharSequence mPrevMonthName; // The last name announced by accessibility + protected int mCurrentMonthDisplayed; // which month should be displayed/highlighted [0-11] + protected long mPreviousScrollPosition; // used for tracking during a scroll + protected int mPreviousScrollState = RecyclerView.SCROLL_STATE_IDLE; // used for tracking what state listview is in + protected int mCurrentScrollState = RecyclerView.SCROLL_STATE_IDLE; // used for tracking what state listview is in + + private DatePickerController mController; + private boolean mPerformingScroll; + protected int mScrollDirection; + + public DayPickerRecyclerView(Context context, DatePickerController controller, int scrollDirection) { + super(context); + mController = controller; + mScrollDirection = scrollDirection; + setUpRecyclerView(); + } + + public DayPickerRecyclerView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public DayPickerRecyclerView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /* + * Sets all the required fields for the recyclerview. Override this method to + * set a different recyclerview behavior. + */ + protected void setUpRecyclerView() { + setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT)); + + setHasFixedSize(true); + setVerticalScrollBarEnabled(false); + setFadingEdgeLength(0); + + LinearLayoutManager layoutManager; + if(mScrollDirection == LinearLayoutManager.VERTICAL || mScrollDirection == LinearLayoutManager.HORIZONTAL) + layoutManager = new LinearLayoutManager(getContext(), mScrollDirection, false); + else layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false); + setLayoutManager(layoutManager); + + refreshAdapter(); + onDateChanged(); + } + + /** + * Creates a new adapter if necessary and sets up its parameters. Override + * this method to provide a custom adapter. + */ + protected void refreshAdapter() { + if (mAdapter == null) { + mAdapter = new MonthRecyclerViewAdapter(getContext(),mController); + } else { + mAdapter.setSelectedDay(mSelectedDay); + } + // refresh the view with the new parameters + setAdapter(mAdapter); + } + + /** + * Gets the position of the view that is most prominently displayed within the list view. + */ + public int getMostVisiblePosition() { + final int firstPosition = ((LinearLayoutManager)getLayoutManager()).findFirstVisibleItemPosition(); + final int height = getHeight(); + + int maxDisplayedHeight = 0; + int mostVisibleIndex = 0; + int i=0; + int bottom = 0; + while (bottom < height) { + View child = getChildAt(i); + if (child == null) { + break; + } + bottom = child.getBottom(); + int displayedHeight = Math.min(bottom, height) - Math.max(0, child.getTop()); + if (displayedHeight > maxDisplayedHeight) { + mostVisibleIndex = i; + maxDisplayedHeight = displayedHeight; + } + i++; + } + return firstPosition + mostVisibleIndex; + } + + public void onChange(){ + refreshAdapter(); + } + + private static String getMonthAndYearString(MonthAdapter.CalendarDay day) { + Calendar cal = Calendar.getInstance(); + cal.set(day.year, day.month, day.day); + + String sbuf = ""; + sbuf += cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()); + sbuf += " "; + sbuf += YEAR_FORMAT.format(cal.getTime()); + return sbuf; + } + + @Override + public void onDateChanged(){ + goTo(mController.getSelectedDay(), false, true, true); + } + + @Override + public void onScrolled(int dx, int dy) { + //mPreviousScrollState = mCurrentScrollState; + } + + @Override + public void onScrollStateChanged(int state) { + // use a post to prevent re-entering onScrollStateChanged before it exits + mScrollStateChangedRunnable.doScrollStateChange(state); + } + + /** + * This moves to the specified time in the view. If the time is not already + * in range it will move the list so that the first of the month containing + * the time is at the top of the view. If the new time is already in view + * the list will not be scrolled unless forceScroll is true. This time may + * optionally be highlighted as selected as well. + * + * @param day The day to move to + * @param animate Whether to scroll to the given time or just redraw at the + * new location + * @param setSelected Whether to set the given time as selected + * @param forceScroll Whether to recenter even if the time is already + * visible + * @return Whether or not the view animated to the new location + */ + public boolean goTo(MonthAdapter.CalendarDay day, boolean animate, boolean setSelected, boolean forceScroll) { + + // Set the selected day + if (setSelected) { + mSelectedDay.set(day); + } + + mTempDay.set(day); + int minMonth = mController.getStartDate().get(Calendar.MONTH); + final int position = (day.year - mController.getMinYear()) + * MonthAdapter.MONTHS_IN_YEAR + day.month - minMonth; + + View child; + int i = 0; + int toporleft; + // Find a child that's completely in the view + do { + child = getChildAt(i++); + if (child == null) { + break; + } + toporleft = mScrollDirection == LinearLayoutManager.VERTICAL ? child.getTop() : child.getLeft(); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "child at " + (i - 1) + " has top " + toporleft); + } + } while (toporleft < 0); + + // Compute the first and last position visible + int selectedPosition; + if (child != null) { + selectedPosition = getLayoutManager().getPosition(child); + } else { + selectedPosition = 0; + } + + if (setSelected) { + mAdapter.setSelectedDay(mSelectedDay); + } + + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "GoTo position " + position); + } + // Check if the selected day is now outside of our visible range + // and if so scroll to the month that contains it + if (position != selectedPosition || forceScroll) { + setMonthDisplayed(mTempDay); + mPreviousScrollState = RecyclerView.SCROLL_STATE_SETTLING; + if (animate) { + smoothScrollToPosition(position); + return true; + } else { + postSetSelection(position); + } + } else if (setSelected) { + setMonthDisplayed(mSelectedDay); + } + return false; + } + + public void postSetSelection(final int position) { + clearFocus(); + post(new Runnable() { + + @Override + public void run() { + scrollToPosition(position); + onScrollStateChanged(RecyclerView.SCROLL_STATE_IDLE); + } + }); + } + + /** + * Sets the month displayed at the top of this view based on time. Override + * to add custom events when the title is changed. + */ + protected void setMonthDisplayed(MonthAdapter.CalendarDay date) { + mCurrentMonthDisplayed = date.month; + invalidate(); + } + + protected ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable(); + + protected class ScrollStateRunnable implements Runnable { + private int mNewState; + + /** + * Sets up the runnable with a short delay in case the scroll state + * immediately changes again. + * + * @param scrollState The new state it changed to + */ + public void doScrollStateChange(int scrollState) { + mHandler = new Handler(); + mHandler.removeCallbacks(this); + mNewState = scrollState; + mHandler.postDelayed(this, SCROLL_CHANGE_DELAY); + } + + @Override + public void run() { + mCurrentScrollState = mNewState; + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, + "new scroll state: " + mNewState + " old state: " + mPreviousScrollState); + } + // Fix the position after a scroll or a fling ends + if (mNewState == RecyclerView.SCROLL_STATE_IDLE + && mPreviousScrollState != RecyclerView.SCROLL_STATE_IDLE + && mPreviousScrollState != RecyclerView.SCROLL_STATE_DRAGGING) { + mPreviousScrollState = mNewState; + + int firstPosition = ((LinearLayoutManager)getLayoutManager()).findFirstVisibleItemPosition(); + int lastPosition = ((LinearLayoutManager)getLayoutManager()).findLastVisibleItemPosition(); + boolean scroll = firstPosition != 0 && lastPosition != getLayoutManager().getChildCount() - 1; + final int midpoint = getHeight() / 2; + int toporleft; + int bottomorright; + + int i = 0; + View child = getChildAt(i); + if(mScrollDirection == LinearLayoutManager.VERTICAL){ + while (child != null && child.getBottom() <= 0) { + child = getChildAt(++i); + } + if (child == null) {return;} // The view is no longer visible, just return + + toporleft = child.getTop(); + bottomorright = child.getBottom(); + + if (scroll && toporleft < LIST_TOP_OFFSET) { + if (bottomorright > midpoint) { + smoothScrollBy(0, toporleft); + } else { + smoothScrollBy(0, bottomorright); + } + } + + }else{ + while (child != null && child.getRight() <= 0) { + child = getChildAt(++i); + } + if (child == null) {return;} // The view is no longer visible, just return + + toporleft = child.getLeft(); + bottomorright = child.getRight(); + + if (scroll && toporleft < LIST_TOP_OFFSET) { + if (bottomorright > midpoint) { + smoothScrollBy(toporleft, 0); + } else { + smoothScrollBy(bottomorright, 0); + } + } + } + + } else { + mPreviousScrollState = mNewState; + } + } + } + +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java index 303488f3..75f9b78b 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerView.java @@ -42,7 +42,7 @@ /** * This displays a list of months in a calendar format with selectable days. */ -public abstract class DayPickerView extends ListView implements OnScrollListener, +public abstract class DayPickerView extends ListView implements DayPickerViewInterface, OnScrollListener, OnDateChangedListener { private static final String TAG = "MonthFragment"; diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerViewInterface.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerViewInterface.java new file mode 100644 index 00000000..9b31d466 --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/DayPickerViewInterface.java @@ -0,0 +1,11 @@ +package com.wdullaer.materialdatetimepicker.date; + +/** + * Created by DroidGreen on 4/6/16. + */ +public interface DayPickerViewInterface { + int getMostVisiblePosition(); + void postSetSelection(final int position); + void onDateChanged(); + void onChange(); +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Events.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Events.java new file mode 100644 index 00000000..fb33130c --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/Events.java @@ -0,0 +1,63 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +public class Events implements Parcelable{ + private int eventColor = -1; + private boolean clickable; + private ArrayList calList = null; + + public Events(boolean clickable){this.clickable = clickable;} + + public boolean isClickable() {return clickable;} + + /** + * @param clickable Set true if user can select an event date. Set false, otherwise. + */ + public void setClickable(boolean clickable) {this.clickable = clickable;} + + public ArrayList getCalList() { + return calList; + } + + /** + * @param calList List of event details including dates and badges (if any). + */ + public void setCalList(ArrayList calList) { + this.calList = calList; + } + + public int getEventColor(){return eventColor;} + + public void setEventColor(int eventColor){this.eventColor = eventColor;} + + //parcelling part + public Events(Parcel in){ + eventColor = in.readInt(); + clickable = (Boolean) in.readValue( null ); + in.readTypedList(calList, CalendarwBadge.CREATOR); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(eventColor); + dest.writeValue(clickable); + dest.writeTypedList(calList); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Events createFromParcel(Parcel in) { + return new Events(in); + } + + public Events[] newArray(int size) {return new Events[size];} + }; +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthAdapter.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthAdapter.java index bc03198a..f5835e09 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthAdapter.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthAdapter.java @@ -106,7 +106,7 @@ public int getDay() { } public MonthAdapter(Context context, - DatePickerController controller) { + DatePickerController controller) { mContext = context; mController = controller; init(); @@ -229,4 +229,4 @@ protected void onDayTapped(CalendarDay day) { mController.onDayOfMonthSelected(day.year, day.month, day.day); setSelectedDay(day); } -} +} \ No newline at end of file diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthRecyclerViewAdapter.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthRecyclerViewAdapter.java new file mode 100644 index 00000000..ef6607ed --- /dev/null +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthRecyclerViewAdapter.java @@ -0,0 +1,125 @@ +package com.wdullaer.materialdatetimepicker.date; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.TextView; + +import com.wdullaer.materialdatetimepicker.R; + +import java.util.Calendar; +import java.util.HashMap; + +public class MonthRecyclerViewAdapter extends RecyclerView.Adapter{ + private static final String TAG = "SimpleMonthAdapter"; + + private final Context mContext; + protected final DatePickerController mController; + + private MonthAdapter.CalendarDay mSelectedDay; + + protected static int WEEK_7_OVERHANG_HEIGHT = 7; + protected static final int MONTHS_IN_YEAR = 12; + + + public MonthRecyclerViewAdapter(Context context, DatePickerController controller) { + mContext = context; + mController = controller; + mSelectedDay = new MonthAdapter.CalendarDay(System.currentTimeMillis()); + setSelectedDay(mController.getSelectedDay()); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public HashMap drawingParams = null; + + public ViewHolder(SimpleMonthView v) { + super(v); + + if (drawingParams == null) { + drawingParams = new HashMap<>(); + } + drawingParams.clear(); + } + } + @Override + public MonthRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + SimpleMonthView v = new SimpleMonthView(mContext, null, mController); + RecyclerView.LayoutParams params = new RecyclerView.LayoutParams( + RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT); + v.setLayoutParams(params); + v.setClickable(true); + v.setOnDayClickListener(new MonthView.OnDayClickListener() { + @Override + public void onDayClick(MonthView view, MonthAdapter.CalendarDay day) { + if (day != null) { + onDayTapped(day); + } + } + }); + + return new ViewHolder(v); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + + final int month = (position + mController.getStartDate().get(Calendar.MONTH)) % MONTHS_IN_YEAR; + final int year = (position + mController.getStartDate().get(Calendar.MONTH)) / MONTHS_IN_YEAR + mController.getMinYear(); + + int selectedDay = -1; + if (isSelectedDayInMonth(year, month)) { + selectedDay = mSelectedDay.day; + } + + // Invokes requestLayout() to ensure that the recycled view is set with the appropriate + // height/number of weeks before being displayed. + //((SimpleMonthView)holder.itemView).reuse(); + + holder.drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_DAY, selectedDay); + holder.drawingParams.put(SimpleMonthView.VIEW_PARAMS_YEAR, year); + holder.drawingParams.put(SimpleMonthView.VIEW_PARAMS_MONTH, month); + holder.drawingParams.put(SimpleMonthView.VIEW_PARAMS_WEEK_START, mController.getFirstDayOfWeek()); + ((SimpleMonthView)holder.itemView).setMonthParams(holder.drawingParams); + holder.itemView.invalidate(); + } + + @Override + public int getItemCount() { + Calendar endDate = mController.getEndDate(); + Calendar startDate = mController.getStartDate(); + int endMonth = endDate.get(Calendar.YEAR) * MONTHS_IN_YEAR + endDate.get(Calendar.MONTH); + int startMonth = startDate.get(Calendar.YEAR) * MONTHS_IN_YEAR + startDate.get(Calendar.MONTH); + return endMonth - startMonth + 1; + //return ((mController.getMaxYear() - mController.getMinYear()) + 1) * MONTHS_IN_YEAR; + } + + private boolean isSelectedDayInMonth(int year, int month) { + return mSelectedDay.year == year && mSelectedDay.month == month; + } + + /** + * Updates the selected day and related parameters. + * + * @param day The day to highlight + */ + public void setSelectedDay(MonthAdapter.CalendarDay day) { + mSelectedDay = day; + notifyDataSetChanged(); + } + + /** + * Maintains the same hour/min/sec but moves the day to the tapped day. + * + * @param day The day that was tapped + */ + protected void onDayTapped(MonthAdapter.CalendarDay day) { + mController.tryVibrate(); + mController.onDayOfMonthSelected(day.year, day.month, day.day); + setSelectedDay(day); + } + +} diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthView.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthView.java index ae184b88..410b6b52 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthView.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/MonthView.java @@ -117,6 +117,8 @@ public abstract class MonthView extends View { protected static int MONTH_DAY_LABEL_TEXT_SIZE; protected static int MONTH_HEADER_SIZE; protected static int DAY_SELECTED_CIRCLE_SIZE; + protected static int BADGE_CIRCLE_SIZE; + protected static int BADGE_NUMBER_TEXT_SIZE; // used for scaling to the device density protected static float mScale = 0; @@ -133,6 +135,8 @@ public abstract class MonthView extends View { protected Paint mMonthTitlePaint; protected Paint mSelectedCirclePaint; protected Paint mMonthDayLabelPaint; + protected Paint mBadgePaint; + protected Paint mBadgeNumPaint; private final Formatter mFormatter; private final StringBuilder mStringBuilder; @@ -229,6 +233,9 @@ public MonthView(Context context, AttributeSet attr, DatePickerController contro MONTH_HEADER_SIZE = res.getDimensionPixelOffset(R.dimen.mdtp_month_list_item_header_height); DAY_SELECTED_CIRCLE_SIZE = res .getDimensionPixelSize(R.dimen.mdtp_day_number_select_circle_radius); + BADGE_CIRCLE_SIZE = res + .getDimensionPixelSize(R.dimen.mdtp_badge_circle_radius); + BADGE_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.mdtp_badge_num_size); mRowHeight = (res.getDimensionPixelOffset(R.dimen.mdtp_date_picker_view_animator_height) - getMonthHeaderSize()) / MAX_NUM_ROWS; @@ -312,7 +319,7 @@ protected void initView() { mMonthDayLabelPaint.setAntiAlias(true); mMonthDayLabelPaint.setTextSize(MONTH_DAY_LABEL_TEXT_SIZE); mMonthDayLabelPaint.setColor(mMonthDayTextColor); - mMonthDayLabelPaint.setTypeface(TypefaceHelper.get(getContext(),"Roboto-Medium")); + mMonthDayLabelPaint.setTypeface(TypefaceHelper.get(getContext(), "Roboto-Medium")); mMonthDayLabelPaint.setStyle(Style.FILL); mMonthDayLabelPaint.setTextAlign(Align.CENTER); mMonthDayLabelPaint.setFakeBoldText(true); @@ -323,6 +330,21 @@ protected void initView() { mMonthNumPaint.setStyle(Style.FILL); mMonthNumPaint.setTextAlign(Align.CENTER); mMonthNumPaint.setFakeBoldText(false); + + mBadgePaint = new Paint(); + mBadgePaint.setAntiAlias(true); + mBadgePaint.setColor(mTodayNumberColor); + mBadgePaint.setTextAlign(Align.CENTER); + mBadgePaint.setStyle(Style.FILL); + mBadgePaint.setAlpha(SELECTED_CIRCLE_ALPHA); + + mBadgeNumPaint = new Paint(); + mBadgeNumPaint.setAntiAlias(true); + mBadgeNumPaint.setTextSize(BADGE_NUMBER_TEXT_SIZE); + mBadgeNumPaint.setColor(mSelectedDayTextColor); + mBadgeNumPaint.setStyle(Style.FILL); + mBadgeNumPaint.setTextAlign(Align.CENTER); + mBadgeNumPaint.setFakeBoldText(false); } @Override @@ -585,6 +607,9 @@ private void onDayClick(int day) { return; } + if(!mController.isEventClickable()&&mController.isEvent(mYear, mMonth, day)){ + return; + } if (mOnDayClickListener != null) { mOnDayClickListener.onDayClick(this, new CalendarDay(mYear, mMonth, day)); @@ -820,4 +845,39 @@ protected CharSequence getItemDescription(int day) { public interface OnDayClickListener { void onDayClick(MonthView view, CalendarDay day); } + + /** + * Draw events & badges based on settings. + */ + protected void drawEvent(Canvas canvas, int x, int y){ + int eventColor = mController.getEventColor(); + mMonthNumPaint.setColor(eventColor==-1?mTodayNumberColor:eventColor); + + CalendarwBadge calendar = mController.getCalendarwBadge(); + if(calendar.getBadgeArrayList()!=null){ + for(Badge badge:calendar.getBadgeArrayList()){ + // default - TOP_LEFT + int xp = x - MINI_DAY_NUMBER_TEXT_SIZE; + int yp = y - (MINI_DAY_NUMBER_TEXT_SIZE / 3) - MINI_DAY_NUMBER_TEXT_SIZE; + switch (badge.getLocation()){ + case Badge.BOTTOM_RIGHT: + xp = x + MINI_DAY_NUMBER_TEXT_SIZE; + yp = y - (MINI_DAY_NUMBER_TEXT_SIZE / 3) + MINI_DAY_NUMBER_TEXT_SIZE; + break; + case Badge.BOTTOM_LEFT: + xp = x - MINI_DAY_NUMBER_TEXT_SIZE; + yp = y - (MINI_DAY_NUMBER_TEXT_SIZE / 3) + MINI_DAY_NUMBER_TEXT_SIZE; + break; + case Badge.TOP_RIGHT: + xp = x + MINI_DAY_NUMBER_TEXT_SIZE; + yp = y - (MINI_DAY_NUMBER_TEXT_SIZE / 3) - MINI_DAY_NUMBER_TEXT_SIZE; + break; + } + + int badgeColor = badge.getColor(); if(badgeColor!=-1)mBadgePaint.setColor(badgeColor); + canvas.drawCircle(xp, yp, BADGE_CIRCLE_SIZE, mBadgePaint); + canvas.drawText(String.format("%d", badge.getDisplayInt()), xp, yp + (MINI_DAY_NUMBER_TEXT_SIZE / 4), mBadgeNumPaint); + } + } + } } diff --git a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/SimpleMonthView.java b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/SimpleMonthView.java index 3533a411..1c5f2af2 100644 --- a/library/src/main/java/com/wdullaer/materialdatetimepicker/date/SimpleMonthView.java +++ b/library/src/main/java/com/wdullaer/materialdatetimepicker/date/SimpleMonthView.java @@ -21,6 +21,8 @@ import android.graphics.Typeface; import android.util.AttributeSet; +import java.util.ArrayList; + public class SimpleMonthView extends MonthView { public SimpleMonthView(Context context, AttributeSet attr, DatePickerController controller) { @@ -51,6 +53,9 @@ else if (mSelectedDay == day) { mMonthNumPaint.setColor(mSelectedDayTextColor); } else if (mHasToday && mToday == day) { mMonthNumPaint.setColor(mTodayNumberColor); + if (mController.isEvent(year, month, day)){drawEvent(canvas,x,y);} + } else if (mController.isEvent(year, month, day)){ + drawEvent(canvas,x,y); } else { mMonthNumPaint.setColor(isHighlighted(year, month, day) ? mHighlightedDayTextColor : mDayTextColor); } diff --git a/library/src/main/res/values/dimens.xml b/library/src/main/res/values/dimens.xml index 4edd9ada..13d06e40 100644 --- a/library/src/main/res/values/dimens.xml +++ b/library/src/main/res/values/dimens.xml @@ -63,6 +63,8 @@ 12sp 64dp 22dp + 6dp + 8sp 48dp 14sp From 2d6caad29fec9d5cd685ef590cbfcc5ebb66aecb Mon Sep 17 00:00:00 2001 From: sasa_droidgreen Date: Thu, 7 Apr 2016 11:44:39 +0100 Subject: [PATCH 2/2] Revert change to original --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3c515a0a..12b6191b 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,18 @@ dpd.show(getFragmentManager(), "Datepickerdialog"); ``` ### Theme the pickers -The pickers will be themed automatically based on the current theme where they are created, based on the current `colorAccent`. You can also theme the dialogs via the `setAccentColor(int eventColor)` method. Alternatively, you can theme the pickers by overwriting the eventColor resources `mdtp_accent_color` and `mdtp_accent_color_dark` in your project. +The pickers will be themed automatically based on the current theme where they are created, based on the current `colorAccent`. You can also theme the dialogs via the `setAccentColor(int color)` method. Alternatively, you can theme the pickers by overwriting the color resources `mdtp_accent_color` and `mdtp_accent_color_dark` in your project. ```xml -#009688 -#00796b +#009688 +#00796b ``` The exact order in which colors are selected is as follows: -1. `setAccentColor(int eventColor)` in java code +1. `setAccentColor(int color)` in java code 2. `android.R.attr.colorAccent` (if android 5.0+) 3. `R.attr.colorAccent` (eg. when using AppCompat) -4. `R.eventColor.mdtp_accent_color` and `R.eventColor.mdtp_accent_color_dark` if none of the others are set in your project +4. `R.color.mdtp_accent_color` and `R.color.mdtp_accent_color_dark` if none of the others are set in your project The pickers also have a dark theme. This can be specified globablly using the `mdtp_theme_dark` attribute in your theme or the `setThemeDark(boolean themeDark)` functions. The function calls overwrite the XML setting. ```xml @@ -111,8 +111,8 @@ The `DatePickerDialog` has a dark theme that can be set by calling dpd.setThemeDark(true); ``` -* `setAccentColor(String eventColor)` and `setAccentColor(int eventColor)` -Set the accentColor to be used by the Dialog. The String version parses the eventColor out using `Color.parseColor()`. The int version requires a ColorInt bytestring. It will explicitly set the eventColor to fully opaque. +* `setAccentColor(String color)` and `setAccentColor(int color)` +Set the accentColor to be used by the Dialog. The String version parses the color out using `Color.parseColor()`. The int version requires a ColorInt bytestring. It will explicitly set the color to fully opaque. * `TimePickerDialog` `setTitle(String title)` Shows a title at the top of the `TimePickerDialog` @@ -139,7 +139,7 @@ Set the interval for selectable times in the TimePickerDialog. This is a conveni You can pass a `Calendar[]` to the `DatePickerDialog`. The values in this list are the only acceptable dates for the picker. It takes precedence over `setMinDate(Calendar day)` and `setMaxDate(Calendar day)` * `setHighlightedDays(Calendar[] days)` -You can pass a `Calendar[]` of days to highlight. They will be rendered in bold. You can tweak the eventColor of the highlighted days by overwriting `mdtp_date_picker_text_highlighted` +You can pass a `Calendar[]` of days to highlight. They will be rendered in bold. You can tweak the color of the highlighted days by overwriting `mdtp_date_picker_text_highlighted` * `showYearPickerFirst(boolean yearPicker)` Show the year picker first, rather than the month and day picker.