Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ public interface DatePickerController {
Calendar getMaxDate();

void tryVibrate();

void pickYear();
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public class DatePickerDialog extends BottomSheetPickerDialog implements
private int mHeaderTextColorUnselected;
private int mDayOfWeekHeaderTextColorSelected;
private int mDayOfWeekHeaderTextColorUnselected;
private boolean mPickDateWithoutDay = false;

/**
* The callback used to indicate the user is done filling in the date.
Expand Down Expand Up @@ -158,6 +159,18 @@ public static DatePickerDialog newInstance(OnDateSetListener callBack, int year,
return ret;
}

/**
* @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.
*/
public static DatePickerDialog newInstance(OnDateSetListener callBack, int year,
int monthOfYear) {
DatePickerDialog ret = new DatePickerDialog();
ret.initialize(callBack, year, monthOfYear, 1);
return ret;
}

void initialize(OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
mCallBack = callBack;
mCalendar.set(Calendar.YEAR, year);
Expand Down Expand Up @@ -255,7 +268,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
}

final Activity activity = getActivity();
mDayPickerView = new PagingDayPickerView(activity, this, mThemeDark, mAccentColor);
mDayPickerView = new PagingDayPickerView(activity, this, mThemeDark, mAccentColor, mPickDateWithoutDay);
mYearPickerView = new YearPickerView(activity, this);
mYearPickerView.setTheme(activity, mThemeDark);
mYearPickerView.setAccentColor(mAccentColor);
Expand Down Expand Up @@ -443,7 +456,7 @@ private void updateHeaderSelectedView(final int viewIndex) {
* of the current locale.
*/
private void determineLocale_MD_Y_Indices() {
String formattedDate = formatMonthDayYear(mCalendar);
String formattedDate = formatMonthDayYear(mCalendar, mPickDateWithoutDay);
// Get the (MD) and Y parts of the formatted date in the current locale,
// so that we can compare their relative positions.
//
Expand All @@ -454,7 +467,7 @@ private void determineLocale_MD_Y_Indices() {
// That is harder than it sounds.
// Different locales use different year delimiters, and some don't use one at all.
// For example, a fully formatted date in the French locale is "30 juin 2009".
String monthAndDay = formatMonthAndDay(mCalendar);
String monthAndDay = formatMonthAndDay(mCalendar, mPickDateWithoutDay);
String year = extractYearFromFormattedDate(formattedDate, monthAndDay);

// All locales format the M and D together; which comes
Expand All @@ -468,13 +481,17 @@ private void determineLocale_MD_Y_Indices() {
}
}

private static String formatMonthDayYear(Calendar calendar) {
private static String formatMonthDayYear(Calendar calendar, boolean mPickDateWithoutDay) {
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_YEAR;
if (mPickDateWithoutDay)
flags |= DateUtils.FORMAT_NO_MONTH_DAY;
return formatDate(calendar, flags);
}

private static String formatMonthAndDay(Calendar calendar) {
private static String formatMonthAndDay(Calendar calendar, boolean mPickDateWithoutDay) {
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_NO_YEAR;
if (mPickDateWithoutDay)
flags |= DateUtils.FORMAT_NO_MONTH_DAY;
return formatDate(calendar, flags);
}

Expand All @@ -491,12 +508,12 @@ private String extractYearFromFormattedDate(String formattedDate, String monthAn
}

private void updateDisplay(boolean announce) {
if (mDayOfWeekView != null) {
if (mDayOfWeekView != null && !mPickDateWithoutDay) {
mDayOfWeekView.setText(mCalendar.getDisplayName(Calendar.DAY_OF_WEEK,
Calendar.LONG, Locale.getDefault()));
}
String fullDate = formatMonthDayYear(mCalendar);
String monthAndDay = formatMonthAndDay(mCalendar);
String fullDate = formatMonthDayYear(mCalendar, mPickDateWithoutDay);
String monthAndDay = formatMonthAndDay(mCalendar, mPickDateWithoutDay);
String year = YEAR_FORMAT.format(mCalendar.getTime());

int yearStart = fullDate.indexOf(year);
Expand Down Expand Up @@ -608,6 +625,21 @@ public void setYearRange(int startYear, int endYear) {
}
}

/**
* In some cases we don't need day, so by this method we can remove day selector form dialog and users
* can pick a date faster
* <em>Default day is 1</em>
*
* @param value make it enable or disable
*/
public void setPickDateWithoutDay(boolean value) {
mPickDateWithoutDay = value;

if (mDayPickerView != null) {
mDayPickerView.onChange();
}
}

/**
* Sets the minimal date that can be selected in this date picker. Dates before (but not including)
* the specified date will be disallowed from being selected.
Expand Down Expand Up @@ -737,6 +769,8 @@ public void onYearSelected(int year) {
updatePickers();
setCurrentView(MONTH_AND_DAY_VIEW);
updateDisplay(true);
if (mDayPickerView != null)
mDayPickerView.onChange();
}

@Override
Expand Down Expand Up @@ -809,6 +843,11 @@ public void tryVibrate() {
mHapticFeedbackController.tryVibrate();
}

@Override
public void pickYear() {
setCurrentView(YEAR_VIEW);
}

@Override
protected int contentLayout() {
return R.layout.bsp_date_picker_dialog;
Expand Down Expand Up @@ -838,6 +877,7 @@ public static class Builder extends BottomSheetPickerDialog.Builder {
private int mHeaderTextColorUnselected;
private int mDayOfWeekHeaderTextColorSelected;
private int mDayOfWeekHeaderTextColorUnselected;
private boolean mPickDateWithoutDay = false;

/**
* @param listener How the parent is notified that the date is set.
Expand All @@ -862,6 +902,30 @@ public Builder setFirstDayOfWeek(int startOfWeek) {
return this;
}

/**
* @param listener 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.
*/
public Builder(OnDateSetListener listener, int year, int monthOfYear) {
mListener = listener;
mYear = year;
mMonthOfYear = monthOfYear;
mDayOfMonth = 1;
}

/**
* In some cases we don't need day, so by this method we can remove day selector form dialog and users
* can pick a date faster
* <em>Default day is 1</em>
*
* @param value make it enable or disable
*/
public Builder setPickDateWithoutDay(boolean value) {
mPickDateWithoutDay = value;
return this;
}

/**
* Sets the range of years to be displayed by this date picker. If a {@link #setMinDate(Calendar)
* minimal date} and/or {@link #setMaxDate(Calendar) maximal date} were set, dates in the
Expand Down Expand Up @@ -980,6 +1044,7 @@ private void build(@NonNull BottomSheetPickerDialog dialog) {
datePickerDialog.setDayOfWeekHeaderTextColorSelected(mDayOfWeekHeaderTextColorSelected);
datePickerDialog.setDayOfWeekHeaderTextColorUnselected(mDayOfWeekHeaderTextColorUnselected);
datePickerDialog.setFirstDayOfWeek(mWeekStart);
datePickerDialog.setPickDateWithoutDay(mPickDateWithoutDay);
if (mMinDate != null) {
datePickerDialog.setMinDate(mMinDate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class PagingDayPickerView extends LinearLayout implements OnDateChangedListener,

private boolean mThemeDark;
private int mAccentColor;
private boolean mPickDateWithoutDay;

public PagingDayPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
Expand All @@ -107,15 +108,16 @@ public PagingDayPickerView(Context context, DatePickerController controller) {
}

public PagingDayPickerView(Context context, DatePickerController controller, boolean themeDark) {
this(context, controller, themeDark, Utils.getThemeAccentColor(context));
this(context, controller, themeDark, Utils.getThemeAccentColor(context), false);
}

public PagingDayPickerView(Context context, DatePickerController controller, boolean themeDark,
int accentColor) {
int accentColor, boolean mPickDateWithoutDay) {
super(context);
// keep these before init()
mThemeDark = themeDark;
mAccentColor = accentColor;
this.mPickDateWithoutDay = mPickDateWithoutDay;
init(context);
setController(controller);
}
Expand Down Expand Up @@ -148,6 +150,10 @@ private void init(Context context) {
mTitleContainer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mPickDateWithoutDay) {
mController.pickYear();
return;
}
int newIndex = mCurrentView == DAY_PICKER_INDEX ? MONTH_PICKER_INDEX : DAY_PICKER_INDEX;
setupCurrentView(newIndex, true);
}
Expand Down Expand Up @@ -228,8 +234,8 @@ public void onChange() {
void setupCurrentView(int currentView, boolean animate) {
if (currentView == DAY_PICKER_INDEX || currentView == MONTH_PICKER_INDEX) {
boolean isDayPicker = currentView == DAY_PICKER_INDEX;
setCurrentView(currentView, animate);
if (isDayPicker) {
setCurrentView(mPickDateWithoutDay ? MONTH_PICKER_INDEX : currentView, animate);
if (isDayPicker && !mPickDateWithoutDay) {
setTitle(mAdapter.getPageTitle(mViewPager.getCurrentItem()));
toggleArrowsVisibility(getPagerPosition());
} else {
Expand Down Expand Up @@ -383,7 +389,7 @@ private void setSelectedDay(CalendarDay day) {
@Override
public void onDateChanged() {
if (mCurrentView != DAY_PICKER_INDEX) {
setCurrentView(DAY_PICKER_INDEX, false);
setCurrentView(mPickDateWithoutDay ? MONTH_PICKER_INDEX : DAY_PICKER_INDEX, false);
// Restore the title and cursors
onPageSelected(mViewPager.getCurrentItem());
}
Expand Down Expand Up @@ -529,10 +535,10 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse
@Override
public void onPageSelected(int position) {
if (mCurrentView == DAY_PICKER_INDEX) {
setTitle(mAdapter.getPageTitle(position));
toggleArrowsVisibility(position);
final int month = mAdapter.getMonth(position);
final int year = mAdapter.getYear(position);
setTitle(mPickDateWithoutDay ? year + "" : mAdapter.getPageTitle(position));
toggleArrowsVisibility(position);
if (mCurrentYearDisplayed != year) {
mCurrentYearDisplayed = year;
}
Expand All @@ -558,6 +564,9 @@ private void setTitle(CharSequence title) {
* @param position The page position
*/
private void toggleArrowsVisibility(int position) {
if (mPickDateWithoutDay)
toggleArrowsVisibility(false, false);
else
toggleArrowsVisibility(position > 0, position + 1 < mAdapter.getCount());
}

Expand All @@ -568,9 +577,9 @@ private void toggleArrowsVisibility(boolean leftVisible, boolean rightVisible) {

private void setArrowDrawableOnTitle(@NonNull Drawable arrow) {
if (Utils.checkApiLevel(17)) {
mMonthYearTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, arrow, null);
mMonthYearTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mPickDateWithoutDay ? null : arrow, null);
} else {
mMonthYearTitleView.setCompoundDrawablesWithIntrinsicBounds(null, null, arrow, null);
mMonthYearTitleView.setCompoundDrawablesWithIntrinsicBounds(null, null, mPickDateWithoutDay ? null : arrow, null);
}
}

Expand All @@ -589,12 +598,11 @@ private void setCurrentView(final int viewIndex, boolean animate) {
}
break;
case MONTH_PICKER_INDEX:
if (mCurrentView != viewIndex) {
prepareMonthPickerForDisplay(mCurrentYearDisplayed);
mMonthAnimator.setDisplayedChild(MONTH_PICKER_INDEX, animate);
animateArrow(mArrowDownDrawable);
mCurrentView = viewIndex;
}
prepareMonthPickerForDisplay(mCurrentYearDisplayed);
mMonthAnimator.setDisplayedChild(MONTH_PICKER_INDEX, animate && !mPickDateWithoutDay);
refreshMonthPicker();
animateArrow(mArrowDownDrawable);
mCurrentView = viewIndex;
break;
}
}
Expand All @@ -610,7 +618,7 @@ public void onMonthClick(MonthPickerView view, int month, int year) {
// setCurrentView() is called with the 'animate' parameter set to false.
// This next call would subsequently not call through, since the current
// index will have already been set to DAY_PICKER_INDEX.
setCurrentView(DAY_PICKER_INDEX, true);
setCurrentView(mPickDateWithoutDay ? MONTH_PICKER_INDEX : DAY_PICKER_INDEX, true);
// If the same month was selected, onPageSelected() won't automatically
// call through because we're staying on the same page.
// This must be called before everything else, ESPECIALLY for the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ private DialogFragment createDialogWithBuilders(int checkedId) {
case R.id.choice_date_picker:
case R.id.choice_date_picker_dark:
case R.id.choice_date_picker_custom:
case R.id.choice_date_picker_without_day:
case R.id.choice_date_picker_custom_dark: {
custom = checkedId == R.id.choice_date_picker_custom;
customDark = checkedId == R.id.choice_date_picker_custom_dark;
Expand Down Expand Up @@ -210,6 +211,7 @@ private DialogFragment createDialogWithSetters(int checkedId) {
case R.id.choice_date_picker:
case R.id.choice_date_picker_dark:
case R.id.choice_date_picker_custom:
case R.id.choice_date_picker_without_day:
case R.id.choice_date_picker_custom_dark: {
Calendar now = Calendar.getInstance();
dialog = DatePickerDialog.newInstance(
Expand All @@ -226,6 +228,7 @@ private DialogFragment createDialogWithSetters(int checkedId) {
max.add(Calendar.YEAR, 10);
dateDialog.setMaxDate(max);
dateDialog.setYearRange(1970, 2032);
dateDialog.setPickDateWithoutDay(checkedId == R.id.choice_date_picker_without_day);
if (custom || customDark) {
dateDialog.setHeaderTextColorSelected(0xFFFF4081);
dateDialog.setHeaderTextColorUnselected(0x4AFF4081);
Expand Down
6 changes: 6 additions & 0 deletions sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
android:layout_height="48dp"
android:text="Date Picker, Custom Dark"/>

<RadioButton
android:id="@+id/choice_date_picker_without_day"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="Date Picker, Without day"/>

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
Expand Down