diff --git a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerController.java b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerController.java
index d44a059..add8881 100644
--- a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerController.java
+++ b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerController.java
@@ -48,4 +48,6 @@ public interface DatePickerController {
Calendar getMaxDate();
void tryVibrate();
+
+ void pickYear();
}
diff --git a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerDialog.java b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerDialog.java
index 195749c..04e6bdc 100644
--- a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerDialog.java
+++ b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/DatePickerDialog.java
@@ -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.
@@ -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);
@@ -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);
@@ -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.
//
@@ -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
@@ -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);
}
@@ -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);
@@ -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
+ * Default day is 1
+ *
+ * @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.
@@ -737,6 +769,8 @@ public void onYearSelected(int year) {
updatePickers();
setCurrentView(MONTH_AND_DAY_VIEW);
updateDisplay(true);
+ if (mDayPickerView != null)
+ mDayPickerView.onChange();
}
@Override
@@ -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;
@@ -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.
@@ -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
+ * Default day is 1
+ *
+ * @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
@@ -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);
}
diff --git a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/PagingDayPickerView.java b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/PagingDayPickerView.java
index c1640d1..5518097 100644
--- a/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/PagingDayPickerView.java
+++ b/bottomsheetpickers/src/main/java/com/philliphsu/bottomsheetpickers/date/PagingDayPickerView.java
@@ -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);
@@ -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);
}
@@ -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);
}
@@ -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 {
@@ -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());
}
@@ -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;
}
@@ -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());
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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
diff --git a/sample/src/main/java/com/example/bottomsheetpickers/MainActivity.java b/sample/src/main/java/com/example/bottomsheetpickers/MainActivity.java
index c1d5ea2..de69081 100644
--- a/sample/src/main/java/com/example/bottomsheetpickers/MainActivity.java
+++ b/sample/src/main/java/com/example/bottomsheetpickers/MainActivity.java
@@ -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;
@@ -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(
@@ -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);
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
index 2d64a0e..37af70e 100644
--- a/sample/src/main/res/layout/activity_main.xml
+++ b/sample/src/main/res/layout/activity_main.xml
@@ -94,6 +94,12 @@
android:layout_height="48dp"
android:text="Date Picker, Custom Dark"/>
+
+