diff --git a/build.gradle b/build.gradle index 33e7a5d..8b9b1cb 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,11 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' - classpath 'com.novoda:bintray-release:0.4.0' + classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.novoda:bintray-release:0.8.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -15,5 +16,6 @@ buildscript { allprojects { repositories { jcenter() + google() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fb19cf7..e27b027 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Dec 28 19:54:34 CET 2016 +#Wed Aug 29 12:28:21 EET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index 8b4f57a..aa60b26 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -16,14 +16,14 @@ publish { android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 27 + buildToolsVersion "27.0.3" defaultConfig { - minSdkVersion 17 - targetSdkVersion 25 + minSdkVersion 19 + targetSdkVersion 27 versionCode 1 - versionName "1.0.1" + versionName "1.0.2" } buildTypes { release { @@ -39,11 +39,11 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-v4:25.2.0' - compile 'com.android.support:support-v13:25.2.0' - compile 'com.android.support:design:25.2.0' - compile group: 'com.github.msarhan', name: 'ummalqura-calendar', version:'1.1.7' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:support-v4:27.1.1' + implementation 'com.android.support:support-v13:27.1.1' + implementation 'com.android.support:design:27.1.1' + implementation group: 'com.github.msarhan', name: 'ummalqura-calendar', version:'1.1.9' } diff --git a/library/library.iml b/library/library.iml index e7da977..68dc6e5 100644 --- a/library/library.iml +++ b/library/library.iml @@ -28,20 +28,21 @@ + - + - + @@ -56,6 +57,13 @@ + + + + + + + @@ -63,13 +71,6 @@ - - - - - - - @@ -77,33 +78,48 @@ - - + + + + + + + + + + + + - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DatePickerController.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DatePickerController.java index fc5eade..49db443 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DatePickerController.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DatePickerController.java @@ -17,6 +17,7 @@ package net.alhazmy13.hijridatepicker.date.gregorian; import java.util.Calendar; +import java.util.Locale; import java.util.TimeZone; /** @@ -37,7 +38,7 @@ public interface DatePickerController { boolean isThemeDark(); int getAccentColor(); - + boolean isHighlighted(int year, int month, int day); int getFirstDayOfWeek(); @@ -55,4 +56,6 @@ public interface DatePickerController { void tryVibrate(); TimeZone getTimeZone(); + + Locale getLocale(); } diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DayPickerView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DayPickerView.java index 2a88159..8072359 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DayPickerView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/DayPickerView.java @@ -43,7 +43,7 @@ * This displays a list of months in a calendar format with selectable days. */ public abstract class DayPickerView extends ListView implements OnScrollListener, - OnDateChangedListener { + OnDateChangedListener { private static final String TAG = "MonthFragment"; @@ -57,7 +57,7 @@ public abstract class DayPickerView extends ListView implements OnScrollListener // The number of days to display in each week public static final int DAYS_PER_WEEK = 7; public static int LIST_TOP_OFFSET = -1; // so that the top line will be - // under the separator + // under the separator // You can override these numbers to get a different appearance protected int mNumWeeks = 6; protected boolean mShowWeekNumber = false; @@ -140,7 +140,7 @@ protected void refreshAdapter() { } public abstract MonthAdapter createMonthAdapter(Context context, - DatePickerController controller); + DatePickerController controller); /* * Sets all the required fields for the list view. Override this method to @@ -169,12 +169,12 @@ protected void setUpListView() { * 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 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 + * visible * @return Whether or not the view animated to the new location */ public boolean goTo(MonthAdapter.CalendarDay day, boolean animate, boolean setSelected, boolean forceScroll) { @@ -292,7 +292,7 @@ protected class ScrollStateRunnable implements Runnable { * Sets up the runnable with a short delay in case the scroll state * immediately changes again. * - * @param view The list view that changed state + * @param view The list view that changed state * @param scrollState The new state it changed to */ public void doScrollStateChange(AbsListView view, int scrollState) { @@ -350,7 +350,7 @@ public int getMostVisiblePosition() { int maxDisplayedHeight = 0; int mostVisibleIndex = 0; - int i=0; + int i = 0; int bottom = 0; while (bottom < height) { View child = getChildAt(i); @@ -377,7 +377,7 @@ public void onDateChanged() { * Attempts to return the date that has accessibility focus. * * @return The date that has accessibility focus, or {@code null} if no date - * has focus. + * has focus. */ private MonthAdapter.CalendarDay findAccessibilityFocus() { final int childCount = getChildCount(); @@ -438,14 +438,14 @@ protected void layoutChildren() { public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setItemCount(-1); - } + } - private static String getMonthAndYearString(MonthAdapter.CalendarDay day) { + private static String getMonthAndYearString(MonthAdapter.CalendarDay day, Locale locale) { Calendar cal = Calendar.getInstance(); cal.set(day.year, day.month, day.day); String sbuf = ""; - sbuf += cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()); + sbuf += cal.getDisplayName(Calendar.MONTH, Calendar.LONG, locale); sbuf += " "; sbuf += YEAR_FORMAT.format(cal.getTime()); return sbuf; @@ -459,11 +459,10 @@ private static String getMonthAndYearString(MonthAdapter.CalendarDay day) { @SuppressWarnings("deprecation") public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - if(Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= 21) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); - } - else { + } else { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); } @@ -510,7 +509,7 @@ public boolean performAccessibilityAction(int action, Bundle arguments) { } // Go to that month. - Utils.tryAccessibilityAnnounce(this, getMonthAndYearString(day)); + Utils.tryAccessibilityAnnounce(this, getMonthAndYearString(day,mController.getLocale())); goTo(day, true, false, true); mPerformingScroll = true; return true; diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/GregorianDatePickerDialog.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/GregorianDatePickerDialog.java index e4e5c6e..b55fcdd 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/GregorianDatePickerDialog.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/GregorianDatePickerDialog.java @@ -157,6 +157,7 @@ public enum Version { private int mCancelColor = -1; private Version mVersion; private TimeZone mTimezone; + public static Locale mLocale = Locale.getDefault(); private HapticFeedbackController mHapticFeedbackController; @@ -174,11 +175,11 @@ public enum Version { public interface OnDateSetListener { /** - * @param view The view associated with this listener. - * @param year The year that was set. + * @param view The view associated with this listener. + * @param year The year that was set. * @param monthOfYear The month that was set (0-11) for compatibility - * with {@link java.util.Calendar}. - * @param dayOfMonth The day of the month that was set. + * with {@link Calendar}. + * @param dayOfMonth The day of the month that was set. */ void onDateSet(GregorianDatePickerDialog view, int year, int monthOfYear, int dayOfMonth); } @@ -197,10 +198,10 @@ public GregorianDatePickerDialog() { } /** - * @param callBack How the parent is notified that the date is set. - * @param year The initial year of the dialog. + * @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. - * @param dayOfMonth The initial day of the dialog. + * @param dayOfMonth The initial day of the dialog. */ public static GregorianDatePickerDialog newInstance(OnDateSetListener callBack, int year, int monthOfYear, @@ -215,6 +216,7 @@ public void initialize(OnDateSetListener callBack, int year, int monthOfYear, in mCalendar.set(Calendar.YEAR, year); mCalendar.set(Calendar.MONTH, monthOfYear); mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); + setTimeZone(mCalendar.getTimeZone()); mVersion = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? Version.VERSION_1 : Version.VERSION_2; } @@ -233,9 +235,9 @@ public void onCreate(Bundle savedInstanceState) { mDefaultView = savedInstanceState.getInt(KEY_DEFAULT_VIEW); } if (Build.VERSION.SDK_INT < 18) { - VERSION_2_FORMAT = new SimpleDateFormat(activity.getResources().getString(R.string.mdtp_date_v2_daymonthyear), Locale.getDefault()); + VERSION_2_FORMAT = new SimpleDateFormat(activity.getResources().getString(R.string.mdtp_date_v2_daymonthyear), mLocale); } else { - VERSION_2_FORMAT = new SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), "EEEMMMdd"), Locale.getDefault()); + VERSION_2_FORMAT = new SimpleDateFormat(DateFormat.getBestDateTimePattern(mLocale, "EEEMMMdd"), mLocale); } VERSION_2_FORMAT.setTimeZone(getTimeZone()); } @@ -283,7 +285,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { int listPosition = -1; int listPositionOffset = 0; int currentView = mDefaultView; @@ -294,8 +296,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, currentView = savedInstanceState.getInt(KEY_CURRENT_VIEW); listPosition = savedInstanceState.getInt(KEY_LIST_POSITION); listPositionOffset = savedInstanceState.getInt(KEY_LIST_POSITION_OFFSET); - mMinDate = (Calendar)savedInstanceState.getSerializable(KEY_MIN_DATE); - mMaxDate = (Calendar)savedInstanceState.getSerializable(KEY_MAX_DATE); + mMinDate = (Calendar) savedInstanceState.getSerializable(KEY_MIN_DATE); + mMaxDate = (Calendar) savedInstanceState.getSerializable(KEY_MAX_DATE); highlightedDays = (HashSet) savedInstanceState.getSerializable(KEY_HIGHLIGHTED_DAYS); selectableDays = (TreeSet) savedInstanceState.getSerializable(KEY_SELECTABLE_DAYS); disabledDays = (HashSet) savedInstanceState.getSerializable(KEY_DISABLED_DAYS); @@ -371,7 +373,7 @@ public void onClick(View v) { } }); okButton.setTypeface(TypefaceHelper.get(activity, "Roboto-Medium")); - if(mOkString != null) okButton.setText(mOkString); + if (mOkString != null) okButton.setText(mOkString); else okButton.setText(mOkResid); Button cancelButton = (Button) view.findViewById(R.id.mdtp_cancel); @@ -379,11 +381,11 @@ public void onClick(View v) { @Override public void onClick(View v) { tryVibrate(); - if(getDialog() != null) getDialog().cancel(); + if (getDialog() != null) getDialog().cancel(); } }); - cancelButton.setTypeface(TypefaceHelper.get(activity,"Roboto-Medium")); - if(mCancelString != null) cancelButton.setText(mCancelString); + cancelButton.setTypeface(TypefaceHelper.get(activity, "Roboto-Medium")); + if (mCancelString != null) cancelButton.setText(mCancelString); else cancelButton.setText(mCancelResid); cancelButton.setVisibility(isCancelable() ? View.VISIBLE : View.GONE); @@ -391,7 +393,8 @@ public void onClick(View v) { if (mAccentColor == -1) { mAccentColor = Utils.getAccentColorFromThemeIfAvailable(getActivity()); } - if(mDatePickerHeaderView != null) mDatePickerHeaderView.setBackgroundColor(Utils.darkenColor(mAccentColor)); + if (mDatePickerHeaderView != null) + mDatePickerHeaderView.setBackgroundColor(Utils.darkenColor(mAccentColor)); view.findViewById(R.id.mdtp_day_picker_selected_date_layout).setBackgroundColor(mAccentColor); // Buttons can have a different color @@ -400,7 +403,7 @@ public void onClick(View v) { if (mCancelColor != -1) cancelButton.setTextColor(mCancelColor); else cancelButton.setTextColor(mAccentColor); - if(getDialog() == null) { + if (getDialog() == null) { view.findViewById(R.id.mdtp_done_background).setVisibility(View.GONE); } @@ -447,19 +450,19 @@ public void onResume() { public void onPause() { super.onPause(); mHapticFeedbackController.stop(); - if(mDismissOnPause) dismiss(); + if (mDismissOnPause) dismiss(); } @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); - if(mOnCancelListener != null) mOnCancelListener.onCancel(dialog); + if (mOnCancelListener != null) mOnCancelListener.onCancel(dialog); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); - if(mOnDismissListener != null) mOnDismissListener.onDismiss(dialog); + if (mOnDismissListener != null) mOnDismissListener.onDismiss(dialog); } private void setCurrentView(final int viewIndex) { @@ -494,7 +497,7 @@ private void setCurrentView(final int viewIndex) { int flags = DateUtils.FORMAT_SHOW_DATE; String dayString = DateUtils.formatDateTime(getActivity(), millis, flags); - mAnimator.setContentDescription(mDayPickerDescription+": "+dayString); + mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString); Utils.tryAccessibilityAnnounce(mAnimator, mSelectDay); break; case YEAR_VIEW: @@ -523,32 +526,32 @@ private void setCurrentView(final int viewIndex) { } CharSequence yearString = YEAR_FORMAT.format(millis); - mAnimator.setContentDescription(mYearPickerDescription+": "+yearString); + mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString); Utils.tryAccessibilityAnnounce(mAnimator, mSelectYear); break; } } private void updateDisplay(boolean announce) { - mYearView.setText(YEAR_FORMAT.format(mCalendar.getTime())); + mYearView.setText(String.format(getLocale(), "%2d", mCalendar.get(Calendar.YEAR))); if (mVersion == Version.VERSION_1) { if (mDatePickerHeaderView != null) { if (mTitle != null) - mDatePickerHeaderView.setText(mTitle.toUpperCase(Locale.getDefault())); + mDatePickerHeaderView.setText(mTitle.toUpperCase(getLocale())); else { mDatePickerHeaderView.setText(mCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, - Locale.getDefault()).toUpperCase(Locale.getDefault())); + getLocale()).toUpperCase(getLocale())); } } - mSelectedMonthTextView.setText(MONTH_FORMAT.format(mCalendar.getTime())); - mSelectedDayTextView.setText(DAY_FORMAT.format(mCalendar.getTime())); + mSelectedMonthTextView.setText(String.valueOf(mCalendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, getLocale()))); + mSelectedDayTextView.setText(String.format(getLocale(), "%2d", mCalendar.get(Calendar.DAY_OF_MONTH))); } if (mVersion == Version.VERSION_2) { - mSelectedDayTextView.setText(VERSION_2_FORMAT.format(mCalendar.getTime())); + mSelectedDayTextView.setText(String.format(getLocale(), VERSION_2_FORMAT.format(mCalendar.getTime()))); if (mTitle != null) - mDatePickerHeaderView.setText(mTitle.toUpperCase(Locale.getDefault())); + mDatePickerHeaderView.setText(mTitle.toUpperCase(mLocale)); else mDatePickerHeaderView.setVisibility(View.GONE); } @@ -569,6 +572,7 @@ private void updateDisplay(boolean announce) { /** * Set whether the device should vibrate when touching fields + * * @param vibrate true if the device should vibrate when touching a field */ public void vibrate(boolean vibrate) { @@ -577,6 +581,7 @@ public void vibrate(boolean vibrate) { /** * Set whether the picker should dismiss itself when being paused or whether it should try to survive an orientation change + * * @param dismissOnPause true if the dialog should dismiss itself when it's pausing */ public void dismissOnPause(boolean dismissOnPause) { @@ -585,6 +590,7 @@ public void dismissOnPause(boolean dismissOnPause) { /** * Set whether the picker should dismiss itself when a day is selected + * * @param autoDismiss true if the dialog should dismiss itself when a day is selected */ @SuppressWarnings("unused") @@ -594,6 +600,7 @@ public void autoDismiss(boolean autoDismiss) { /** * Set whether the dark theme should be used + * * @param themeDark true if the dark theme should be used, false if the default theme should be used */ public void setThemeDark(boolean themeDark) { @@ -603,6 +610,7 @@ public void setThemeDark(boolean themeDark) { /** * Returns true when the dark theme should be used + * * @return true if the dark theme should be used, false if the default theme should be used */ @Override @@ -612,6 +620,7 @@ public boolean isThemeDark() { /** * Set the accent color of this dialog + * * @param color the accent color you want */ @SuppressWarnings("unused") @@ -621,6 +630,7 @@ public void setAccentColor(String color) { /** * Set the accent color of this dialog + * * @param color the accent color you want */ public void setAccentColor(@ColorInt int color) { @@ -629,6 +639,7 @@ public void setAccentColor(@ColorInt int color) { /** * Set the text color of the OK button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -638,6 +649,7 @@ public void setOkColor(String color) { /** * Set the text color of the OK button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -647,6 +659,7 @@ public void setOkColor(@ColorInt int color) { /** * Set the text color of the Cancel button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -656,6 +669,7 @@ public void setCancelColor(String color) { /** * Set the text color of the Cancel button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -665,6 +679,7 @@ public void setCancelColor(@ColorInt int color) { /** * Get the accent color of this dialog + * * @return accent color */ @Override @@ -674,6 +689,7 @@ public int getAccentColor() { /** * Set whether the year picker of the month and day picker is shown first + * * @param yearPicker boolean */ public void showYearPickerFirst(boolean yearPicker) { @@ -708,6 +724,7 @@ public void setYearRange(int startYear, int endYear) { /** * Sets the minimal date supported by this DatePicker. Dates before (but not including) the * specified date will be disallowed from being selected. + * * @param calendar a Calendar object set to the year, month, day desired as the mindate. */ @SuppressWarnings("unused") @@ -730,6 +747,7 @@ public Calendar getMinDate() { /** * Sets the minimal date supported by this DatePicker. Dates after (but not including) the * specified date will be disallowed from being selected. + * * @param calendar a Calendar object set to the year, month, day desired as the maxdate. */ @SuppressWarnings("unused") @@ -751,6 +769,7 @@ public Calendar getMaxDate() { /** * Sets an array of dates which should be highlighted when the picker is drawn + * * @param highlightedDays an Array of Calendar objects containing the dates to be highlighted */ @SuppressWarnings("unused") @@ -784,6 +803,7 @@ public boolean isHighlighted(int year, int month, int day) { /** * Sets a list of days which are the only valid selections. * Setting this value will take precedence over using setMinDate() and setMaxDate() + * * @param selectableDays an Array of Calendar Objects containing the selectable dates */ @SuppressWarnings("unused") @@ -804,6 +824,7 @@ public Calendar[] getSelectableDays() { /** * Sets a list of days that are not selectable in the picker * Setting this value will take precedence over using setMinDate() and setMaxDate(), but stacks with setSelectableDays() + * * @param disabledDays an Array of Calendar Objects containing the disabled dates */ @SuppressWarnings("unused") @@ -826,6 +847,7 @@ public Calendar[] getDisabledDays() { /** * Set a title to be displayed instead of the weekday + * * @param title String - The title to be displayed */ public void setTitle(String title) { @@ -834,6 +856,7 @@ public void setTitle(String title) { /** * Set the label for the Ok button (max 12 characters) + * * @param okString A literal String to be used as the Ok button label */ @SuppressWarnings("unused") @@ -843,6 +866,7 @@ public void setOkText(String okString) { /** * Set the label for the Ok button (max 12 characters) + * * @param okResid A resource ID to be used as the Ok button label */ @SuppressWarnings("unused") @@ -853,6 +877,7 @@ public void setOkText(@StringRes int okResid) { /** * Set the label for the Cancel button (max 12 characters) + * * @param cancelString A literal String to be used as the Cancel button label */ @SuppressWarnings("unused") @@ -862,6 +887,7 @@ public void setCancelText(String cancelString) { /** * Set the label for the Cancel button (max 12 characters) + * * @param cancelResid A resource ID to be used as the Cancel button label */ @SuppressWarnings("unused") @@ -872,6 +898,7 @@ public void setCancelText(@StringRes int cancelResid) { /** * Set which layout version the picker should use + * * @param version The version to use */ public void setVersion(Version version) { @@ -880,6 +907,7 @@ public void setVersion(Version version) { /** * Set which timezone the picker should use + * * @param timeZone The timezone to use */ @SuppressWarnings("unused") @@ -891,6 +919,14 @@ public void setTimeZone(TimeZone timeZone) { DAY_FORMAT.setTimeZone(timeZone); } + public void setLocale(Locale locale) { + mLocale = locale; + mWeekStart = Calendar.getInstance(mTimezone, mLocale).getFirstDayOfWeek(); + YEAR_FORMAT = new SimpleDateFormat("yyyy", locale); + MONTH_FORMAT = new SimpleDateFormat("MMM", locale); + DAY_FORMAT = new SimpleDateFormat("dd", locale); + } + @SuppressWarnings("unused") public void setOnDateSetListener(OnDateSetListener listener) { mCallBack = listener; @@ -952,7 +988,7 @@ public void onDayOfMonthSelected(int year, int month, int day) { } private void updatePickers() { - for(OnDateChangedListener listener : mListeners) listener.onDateChanged(); + for (OnDateChangedListener listener : mListeners) listener.onDateChanged(); } @@ -1084,12 +1120,12 @@ private void setToNearestDate(Calendar calendar) { } - if(isBeforeMin(calendar)) { + if (isBeforeMin(calendar)) { calendar.setTimeInMillis(mMinDate.getTimeInMillis()); return; } - if(isAfterMax(calendar)) { + if (isAfterMax(calendar)) { calendar.setTimeInMillis(mMaxDate.getTimeInMillis()); return; } @@ -1098,6 +1134,7 @@ private void setToNearestDate(Calendar calendar) { /** * Trims off all time information, effectively setting it to midnight * Makes it easier to compare at just the day level + * * @param calendar The Calendar object to trim * @return The trimmed Calendar object */ @@ -1126,13 +1163,19 @@ public void unregisterOnDateChangedListener(OnDateChangedListener listener) { @Override public void tryVibrate() { - if(mVibrate) mHapticFeedbackController.tryVibrate(); + if (mVibrate) mHapticFeedbackController.tryVibrate(); } - @Override public TimeZone getTimeZone() { + @Override + public TimeZone getTimeZone() { return mTimezone == null ? TimeZone.getDefault() : mTimezone; } + @Override + public Locale getLocale() { + return mLocale; + } + public void notifyOnDateListener() { if (mCallBack != null) { mCallBack.onDateSet(GregorianDatePickerDialog.this, mCalendar.get(Calendar.YEAR), diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/MonthView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/MonthView.java index 7459bfc..030db78 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/MonthView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/MonthView.java @@ -197,20 +197,19 @@ public MonthView(Context context, AttributeSet attr, DatePickerController contro mController = controller; Resources res = context.getResources(); - mDayLabelCalendar = Calendar.getInstance(mController.getTimeZone()); - mCalendar = Calendar.getInstance(mController.getTimeZone()); + mDayLabelCalendar = Calendar.getInstance(mController.getTimeZone(), mController.getLocale()); + mCalendar = Calendar.getInstance(mController.getTimeZone(), mController.getLocale()); mDayOfWeekTypeface = res.getString(R.string.mdtp_day_of_week_label_typeface); mMonthTitleTypeface = res.getString(R.string.mdtp_sans_serif); boolean darkTheme = mController != null && mController.isThemeDark(); - if(darkTheme) { + if (darkTheme) { mDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_normal_dark_theme); mMonthDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_month_day_dark_theme); mDisabledDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_disabled_dark_theme); mHighlightedDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_highlighted_dark_theme); - } - else { + } else { mDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_normal); mMonthDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_month_day); mDisabledDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_disabled); @@ -221,7 +220,7 @@ public MonthView(Context context, AttributeSet attr, DatePickerController contro mMonthTitleColor = ContextCompat.getColor(context, R.color.mdtp_white); mStringBuilder = new StringBuilder(50); - mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); + mFormatter = new Formatter(mStringBuilder, mController.getLocale()); MINI_DAY_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.mdtp_day_number_size); MONTH_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.mdtp_month_label_size); @@ -299,6 +298,7 @@ protected void initView() { mMonthTitlePaint.setColor(mDayTextColor); mMonthTitlePaint.setTextAlign(Align.CENTER); mMonthTitlePaint.setStyle(Style.FILL); + mMonthTitlePaint.setTextLocale(mController.getLocale()); mSelectedCirclePaint = new Paint(); mSelectedCirclePaint.setFakeBoldText(true); @@ -312,10 +312,11 @@ 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); + mMonthDayLabelPaint.setTextLocale(mController.getLocale()); mMonthNumPaint = new Paint(); mMonthNumPaint.setAntiAlias(true); @@ -323,6 +324,7 @@ protected void initView() { mMonthNumPaint.setStyle(Style.FILL); mMonthNumPaint.setTextAlign(Align.CENTER); mMonthNumPaint.setFakeBoldText(false); + mMonthNumPaint.setTextLocale(mController.getLocale()); } @Override @@ -342,7 +344,7 @@ protected void onDraw(Canvas canvas) { * {@link #VIEW_PARAMS_HEIGHT} for more info on parameters. * * @param params A map of the new parameters, see - * {@link #VIEW_PARAMS_HEIGHT} + * {@link #VIEW_PARAMS_HEIGHT} */ public void setMonthParams(HashMap params) { if (!params.containsKey(VIEW_PARAMS_MONTH) && !params.containsKey(VIEW_PARAMS_YEAR)) { @@ -449,10 +451,11 @@ protected int getMonthHeaderSize() { @NonNull private String getMonthAndYearString() { - Locale locale = Locale.getDefault(); + Locale locale = mController.getLocale(); String pattern = "MMMM yyyy"; - if(Build.VERSION.SDK_INT < 18) pattern = getContext().getResources().getString(R.string.mdtp_date_v1_monthyear); + if (Build.VERSION.SDK_INT < 18) + pattern = getContext().getResources().getString(R.string.mdtp_date_v1_monthyear); else pattern = DateFormat.getBestDateTimePattern(locale, pattern); SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale); @@ -494,14 +497,14 @@ protected void drawMonthNums(Canvas canvas) { final float dayWidthHalf = (mWidth - mEdgePadding * 2) / (mNumDays * 2.0f); int j = findDayOffset(); for (int dayNumber = 1; dayNumber <= mNumCells; dayNumber++) { - final int x = (int)((2 * j + 1) * dayWidthHalf + mEdgePadding); + final int x = (int) ((2 * j + 1) * dayWidthHalf + mEdgePadding); int yRelativeToDay = (mRowHeight + MINI_DAY_NUMBER_TEXT_SIZE) / 2 - DAY_SEPARATOR_WIDTH; - final int startX = (int)(x - dayWidthHalf); - final int stopX = (int)(x + dayWidthHalf); - final int startY = (int)(y - yRelativeToDay); - final int stopY = (int)(startY + mRowHeight); + final int startX = (int) (x - dayWidthHalf); + final int stopX = (int) (x + dayWidthHalf); + final int startY = (int) (y - yRelativeToDay); + final int stopY = (int) (startY + mRowHeight); drawMonthDay(canvas, mYear, mMonth, dayNumber, x, y, startX, stopX, startY, stopY); @@ -516,19 +519,19 @@ protected void drawMonthNums(Canvas canvas) { /** * This method should draw the month day. Implemented by sub-classes to allow customization. * - * @param canvas The canvas to draw on - * @param year The year of this month day + * @param canvas The canvas to draw on + * @param year The year of this month day * @param month The month of this month day - * @param day The day number of this month day - * @param x The default x position to draw the day number - * @param y The default y position to draw the day number - * @param startX The left boundary of the day number rect + * @param day The day number of this month day + * @param x The default x position to draw the day number + * @param y The default y position to draw the day number + * @param startX The left boundary of the day number rect * @param stopX The right boundary of the day number rect - * @param startY The top boundary of the day number rect + * @param startY The top boundary of the day number rect * @param stopY The bottom boundary of the day number rect */ public abstract void drawMonthDay(Canvas canvas, int year, int month, int day, - int x, int y, int startX, int stopX, int startY, int stopY); + int x, int y, int startX, int stopX, int startY, int stopY); protected int findDayOffset() { return (mDayOfWeekStart < mWeekStart ? (mDayOfWeekStart + mNumDays) : mDayOfWeekStart) @@ -607,30 +610,30 @@ protected boolean isHighlighted(int year, int month, int day) { /** * Return a 1 or 2 letter String for use as a weekday label + * * @param day The day for which to generate a label * @return The weekday label */ private String getWeekDayLabel(Calendar day) { - Locale locale = Locale.getDefault(); + Locale locale = mController.getLocale(); // Localised short version of the string is not available on API < 18 - if(Build.VERSION.SDK_INT < 18) { + if (Build.VERSION.SDK_INT < 18) { String dayName = new SimpleDateFormat("E", locale).format(day.getTime()); String dayLabel = dayName.toUpperCase(locale).substring(0, 1); // Chinese labels should be fetched right to left if (locale.equals(Locale.CHINA) || locale.equals(Locale.CHINESE) || locale.equals(Locale.SIMPLIFIED_CHINESE) || locale.equals(Locale.TRADITIONAL_CHINESE)) { int len = dayName.length(); - dayLabel = dayName.substring(len -1, len); + dayLabel = dayName.substring(len - 1, len); } // Most hebrew labels should select the second to last character if (locale.getLanguage().equals("he") || locale.getLanguage().equals("iw")) { - if(mDayLabelCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { + if (mDayLabelCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { int len = dayName.length(); dayLabel = dayName.substring(len - 2, len - 1); - } - else { + } else { // I know this is duplication, but it makes the code easier to grok by // having all hebrew code in the same block dayLabel = dayName.toUpperCase(locale).substring(0, 1); @@ -639,7 +642,7 @@ private String getWeekDayLabel(Calendar day) { // Catalan labels should be two digits in lowercase if (locale.getLanguage().equals("ca")) - dayLabel = dayName.toLowerCase().substring(0,2); + dayLabel = dayName.toLowerCase().substring(0, 2); // Correct single character label in Spanish is X if (locale.getLanguage().equals("es") && day.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY) @@ -653,7 +656,7 @@ private String getWeekDayLabel(Calendar day) { /** * @return The date that has accessibility focus, or {@code null} if no date - * has focus + * has focus */ public CalendarDay getAccessibilityFocus() { final int day = mTouchHelper.getFocusedVirtualView(); @@ -676,7 +679,7 @@ public void clearAccessibilityFocus() { * * @param day The date which should receive focus * @return {@code false} if the date is not valid for this month view, or - * {@code true} if the date received focus + * {@code true} if the date received focus */ public boolean restoreAccessibilityFocus(CalendarDay day) { if ((day.year != mYear) || (day.month != mMonth) || (day.day > mNumCells)) { @@ -738,7 +741,7 @@ protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEve @Override protected void onPopulateNodeForVirtualView(int virtualViewId, - AccessibilityNodeInfoCompat node) { + AccessibilityNodeInfoCompat node) { getItemBounds(virtualViewId, mTempRect); node.setContentDescription(getItemDescription(virtualViewId)); @@ -753,7 +756,7 @@ protected void onPopulateNodeForVirtualView(int virtualViewId, @Override protected boolean onPerformActionForVirtualView(int virtualViewId, int action, - Bundle arguments) { + Bundle arguments) { switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: onDayClick(virtualViewId); @@ -766,7 +769,7 @@ protected boolean onPerformActionForVirtualView(int virtualViewId, int action, /** * Calculates the bounding rectangle of a given time object. * - * @param day The day to calculate bounds for + * @param day The day to calculate bounds for * @param rect The rectangle in which to store the bounds */ protected void getItemBounds(int day, Rect rect) { diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/YearPickerView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/YearPickerView.java index 7de0492..73db234 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/YearPickerView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/gregorian/YearPickerView.java @@ -125,12 +125,12 @@ public View getView(int position, View convertView, ViewGroup parent) { v = (TextViewWithCircularIndicator) convertView; } else { v = (TextViewWithCircularIndicator) LayoutInflater.from(parent.getContext()) - .inflate(R.layout.hdp_mdtp_year_label_text_view, parent, false); + .inflate(R.layout.hdp_mdtp_year_label_text_view, parent, false); v.setAccentColor(mController.getAccentColor(), mController.isThemeDark()); } int year = mMinYear + position; boolean selected = mController.getSelectedDay().year == year; - v.setText(String.valueOf(year)); + v.setText(String.format(mController.getLocale(), "%d", year)); v.drawIndicator(selected); v.requestLayout(); if (selected) { diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DatePickerController.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DatePickerController.java index b9ced00..1bd2e9f 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DatePickerController.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DatePickerController.java @@ -18,6 +18,7 @@ import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; +import java.util.Locale; import java.util.TimeZone; /** @@ -38,7 +39,7 @@ public interface DatePickerController { boolean isThemeDark(); int getAccentColor(); - + boolean isHighlighted(int year, int month, int day); int getFirstDayOfWeek(); @@ -56,4 +57,6 @@ public interface DatePickerController { void tryVibrate(); TimeZone getTimeZone(); + + Locale getLocale(); } diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DayPickerView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DayPickerView.java index f206133..6d1c062 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DayPickerView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/DayPickerView.java @@ -31,10 +31,11 @@ import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; -import net.alhazmy13.hijridatepicker.date.hijri.HijriDatePickerDialog.OnDateChangedListener; import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + import net.alhazmy13.hijridatepicker.Utils; +import net.alhazmy13.hijridatepicker.date.hijri.HijriDatePickerDialog.OnDateChangedListener; import java.text.SimpleDateFormat; import java.util.Locale; @@ -57,7 +58,7 @@ public abstract class DayPickerView extends ListView implements OnScrollListener // The number of days to display in each week public static final int DAYS_PER_WEEK = 7; public static int LIST_TOP_OFFSET = -1; // so that the top line will be - // under the separator + // under the separator // You can override these numbers to get a different appearance protected int mNumWeeks = 6; protected boolean mShowWeekNumber = false; @@ -108,6 +109,7 @@ public void setController(DatePickerController controller) { mController.registerOnDateChangedListener(this); mSelectedDay = new MonthAdapter.CalendarDay(mController.getTimeZone()); mTempDay = new MonthAdapter.CalendarDay(mController.getTimeZone()); + YEAR_FORMAT = new SimpleDateFormat("yyyy", mController.getLocale()); refreshAdapter(); onDateChanged(); } @@ -169,12 +171,12 @@ protected void setUpListView() { * 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 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 + * visible * @return Whether or not the view animated to the new location */ public boolean goTo(MonthAdapter.CalendarDay day, boolean animate, boolean setSelected, boolean forceScroll) { @@ -292,7 +294,7 @@ protected class ScrollStateRunnable implements Runnable { * Sets up the runnable with a short delay in case the scroll state * immediately changes again. * - * @param view The list view that changed state + * @param view The list view that changed state * @param scrollState The new state it changed to */ public void doScrollStateChange(AbsListView view, int scrollState) { @@ -350,7 +352,7 @@ public int getMostVisiblePosition() { int maxDisplayedHeight = 0; int mostVisibleIndex = 0; - int i=0; + int i = 0; int bottom = 0; while (bottom < height) { View child = getChildAt(i); @@ -377,7 +379,7 @@ public void onDateChanged() { * Attempts to return the date that has accessibility focus. * * @return The date that has accessibility focus, or {@code null} if no date - * has focus. + * has focus. */ private MonthAdapter.CalendarDay findAccessibilityFocus() { final int childCount = getChildCount(); @@ -438,14 +440,14 @@ protected void layoutChildren() { public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setItemCount(-1); - } + } - private static String getMonthAndYearString(MonthAdapter.CalendarDay day) { + private static String getMonthAndYearString(MonthAdapter.CalendarDay day, Locale locale) { UmmalquraCalendar cal = new UmmalquraCalendar(); cal.set(day.year, day.month, day.day); String sbuf = ""; - sbuf += cal.getDisplayName(UmmalquraCalendar.MONTH, UmmalquraCalendar.SHORT, Locale.getDefault()); + sbuf += cal.getDisplayName(UmmalquraCalendar.MONTH, UmmalquraCalendar.SHORT, locale); sbuf += " "; sbuf += YEAR_FORMAT.format(cal.getTime()); return sbuf; @@ -459,11 +461,10 @@ private static String getMonthAndYearString(MonthAdapter.CalendarDay day) { @SuppressWarnings("deprecation") public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - if(Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= 21) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); - } - else { + } else { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); } @@ -510,7 +511,7 @@ public boolean performAccessibilityAction(int action, Bundle arguments) { } // Go to that month. - Utils.tryAccessibilityAnnounce(this, getMonthAndYearString(day)); + Utils.tryAccessibilityAnnounce(this, getMonthAndYearString(day, mController.getLocale())); goTo(day, true, false, true); mPerformingScroll = true; return true; diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/HijriDatePickerDialog.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/HijriDatePickerDialog.java index 9f82ae1..84c633a 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/HijriDatePickerDialog.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/HijriDatePickerDialog.java @@ -45,6 +45,7 @@ import android.widget.TextView; import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + import net.alhazmy13.hijridatepicker.HapticFeedbackController; import net.alhazmy13.hijridatepicker.R; import net.alhazmy13.hijridatepicker.TypefaceHelper; @@ -64,6 +65,7 @@ public class HijriDatePickerDialog extends DialogFragment implements OnClickListener, DatePickerController { private static final String TAG = "GregorianDatePickerDialog"; + public enum Version { VERSION_1, VERSION_2 @@ -111,12 +113,12 @@ public enum Version { private static final int ANIMATION_DURATION = 300; private static final int ANIMATION_DELAY = 500; - private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("y", getLocal()); - private static SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("MMMM", getLocal()); - private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd", getLocal()); + private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("y", Locale.getDefault()); + private static SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("MMMM", Locale.getDefault()); + private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd", Locale.getDefault()); private static SimpleDateFormat VERSION_2_FORMAT; - private final UmmalquraCalendar mCalendar = trimToMidnight(new UmmalquraCalendar(getTimeZone(), getLocal())); + private final UmmalquraCalendar mCalendar = trimToMidnight(new UmmalquraCalendar(getTimeZone(), Locale.getDefault())); private OnDateSetListener mCallBack; private HashSet mListeners = new HashSet<>(); private DialogInterface.OnCancelListener mOnCancelListener; @@ -158,6 +160,7 @@ public enum Version { private int mCancelColor = -1; private Version mVersion; private TimeZone mTimezone; + public static Locale mLocale = Locale.getDefault(); private HapticFeedbackController mHapticFeedbackController; @@ -216,7 +219,7 @@ public void initialize(OnDateSetListener callBack, int year, int monthOfYear, in mCalendar.set(Calendar.YEAR, year); mCalendar.set(Calendar.MONTH, monthOfYear); mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); - + setTimeZone(mCalendar.getTimeZone()); mVersion = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? Version.VERSION_1 : Version.VERSION_2; } @@ -234,9 +237,9 @@ public void onCreate(Bundle savedInstanceState) { mDefaultView = savedInstanceState.getInt(KEY_DEFAULT_VIEW); } if (Build.VERSION.SDK_INT < 18) { - VERSION_2_FORMAT = new SimpleDateFormat(activity.getResources().getString(R.string.mdtp_date_v2_daymonthyear), Locale.getDefault()); + VERSION_2_FORMAT = new SimpleDateFormat(activity.getResources().getString(R.string.mdtp_date_v2_daymonthyear), getLocale()); } else { - VERSION_2_FORMAT = new SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), "EEEMMMdd"), Locale.getDefault()); + VERSION_2_FORMAT = new SimpleDateFormat(DateFormat.getBestDateTimePattern(getLocale(), "EEEMMMdd"), getLocale()); } VERSION_2_FORMAT.setTimeZone(getTimeZone()); } @@ -532,28 +535,28 @@ private void setCurrentView(final int viewIndex) { } private void updateDisplay(boolean announce) { - mYearView.setText(String.valueOf(mCalendar.get(Calendar.YEAR))); + mYearView.setText(String.format(getLocale(), "%2d", mCalendar.get(Calendar.YEAR))); if (mVersion == Version.VERSION_1) { if (mDatePickerHeaderView != null) { if (mTitle != null) - mDatePickerHeaderView.setText(mTitle.toUpperCase(Locale.getDefault())); + mDatePickerHeaderView.setText(mTitle.toUpperCase(getLocale())); else { mDatePickerHeaderView.setText(mCalendar.getDisplayName(UmmalquraCalendar.DAY_OF_WEEK, UmmalquraCalendar.LONG, - Locale.getDefault()).toUpperCase(Locale.getDefault())); + getLocale()).toUpperCase(getLocale())); } } - mSelectedMonthTextView.setText(String.valueOf(mCalendar.getDisplayName(Calendar.MONTH,Calendar.SHORT,getLocal()))); - mSelectedDayTextView.setText(String.valueOf(mCalendar.get(Calendar.DAY_OF_MONTH))); + mSelectedMonthTextView.setText(String.valueOf(mCalendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, getLocale()))); + mSelectedDayTextView.setText(String.format(getLocale(), "%2d", mCalendar.get(Calendar.DAY_OF_MONTH))); } if (mVersion == Version.VERSION_2) { String day = - mCalendar.getDisplayName(UmmalquraCalendar.DAY_OF_WEEK,UmmalquraCalendar.SHORT,getLocal()) - +", "+ mCalendar.getDisplayName(UmmalquraCalendar.MONTH,UmmalquraCalendar.SHORT,getLocal()) - + " "+mCalendar.get(Calendar.DAY_OF_MONTH); + mCalendar.getDisplayName(UmmalquraCalendar.DAY_OF_WEEK, UmmalquraCalendar.SHORT, getLocale()) + + ", " + mCalendar.getDisplayName(UmmalquraCalendar.MONTH, UmmalquraCalendar.SHORT, getLocale()) + + " " + String.format(getLocale(), "%2d", mCalendar.get(Calendar.DAY_OF_MONTH)); mSelectedDayTextView.setText(day); if (mTitle != null) - mDatePickerHeaderView.setText(mTitle.toUpperCase(Locale.getDefault())); + mDatePickerHeaderView.setText(mTitle.toUpperCase(mLocale)); else mDatePickerHeaderView.setVisibility(View.GONE); } @@ -921,6 +924,14 @@ public void setTimeZone(TimeZone timeZone) { DAY_FORMAT.setTimeZone(timeZone); } + public void setLocale(Locale locale) { + mLocale = locale; + mWeekStart = Calendar.getInstance(mTimezone, mLocale).getFirstDayOfWeek(); + YEAR_FORMAT = new SimpleDateFormat("yyyy", locale); + MONTH_FORMAT = new SimpleDateFormat("MMM", locale); + DAY_FORMAT = new SimpleDateFormat("dd", locale); + } + @SuppressWarnings("unused") public void setOnDateSetListener(OnDateSetListener listener) { mCallBack = listener; @@ -995,7 +1006,7 @@ public MonthAdapter.CalendarDay getSelectedDay() { public UmmalquraCalendar getStartDate() { if (!selectableDays.isEmpty()) return selectableDays.first(); if (mMinDate != null) return mMinDate; - UmmalquraCalendar output = new UmmalquraCalendar(getTimeZone(), getLocal()); + UmmalquraCalendar output = new UmmalquraCalendar(getTimeZone(), getLocale()); output.set(UmmalquraCalendar.YEAR, mMinYear); output.set(UmmalquraCalendar.DAY_OF_MONTH, 1); output.set(UmmalquraCalendar.MONTH, UmmalquraCalendar.JANUARY); @@ -1006,7 +1017,7 @@ public UmmalquraCalendar getStartDate() { public UmmalquraCalendar getEndDate() { if (!selectableDays.isEmpty()) return selectableDays.last(); if (mMaxDate != null) return mMaxDate; - UmmalquraCalendar output = new UmmalquraCalendar(getTimeZone(), getLocal()); + UmmalquraCalendar output = new UmmalquraCalendar(getTimeZone(), getLocale()); output.set(UmmalquraCalendar.YEAR, mMaxYear); output.set(UmmalquraCalendar.DAY_OF_MONTH, 31); output.set(UmmalquraCalendar.MONTH, UmmalquraCalendar.DECEMBER); @@ -1165,8 +1176,9 @@ public TimeZone getTimeZone() { return mTimezone == null ? TimeZone.getDefault() : mTimezone; } - public static Locale getLocal() { - return Locale.getDefault(); + @Override + public Locale getLocale() { + return mLocale; } public void notifyOnDateListener() { diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/MonthView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/MonthView.java index 712160c..8a58735 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/MonthView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/MonthView.java @@ -39,6 +39,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + import net.alhazmy13.hijridatepicker.R; import net.alhazmy13.hijridatepicker.TypefaceHelper; import net.alhazmy13.hijridatepicker.date.hijri.MonthAdapter.CalendarDay; @@ -198,20 +199,19 @@ public MonthView(Context context, AttributeSet attr, DatePickerController contro mController = controller; Resources res = context.getResources(); - mDayLabelCalendar = new UmmalquraCalendar(mController.getTimeZone(),Locale.getDefault()); - mCalendar = new UmmalquraCalendar(mController.getTimeZone(),Locale.getDefault()); + mDayLabelCalendar = new UmmalquraCalendar(mController.getTimeZone(), mController.getLocale()); + mCalendar = new UmmalquraCalendar(mController.getTimeZone(), mController.getLocale()); mDayOfWeekTypeface = res.getString(R.string.mdtp_day_of_week_label_typeface); mMonthTitleTypeface = res.getString(R.string.mdtp_sans_serif); boolean darkTheme = mController != null && mController.isThemeDark(); - if(darkTheme) { + if (darkTheme) { mDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_normal_dark_theme); mMonthDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_month_day_dark_theme); mDisabledDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_disabled_dark_theme); mHighlightedDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_highlighted_dark_theme); - } - else { + } else { mDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_normal); mMonthDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_month_day); mDisabledDayTextColor = ContextCompat.getColor(context, R.color.mdtp_date_picker_text_disabled); @@ -222,7 +222,7 @@ public MonthView(Context context, AttributeSet attr, DatePickerController contro mMonthTitleColor = ContextCompat.getColor(context, R.color.mdtp_white); mStringBuilder = new StringBuilder(50); - mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); + mFormatter = new Formatter(mStringBuilder, mController.getLocale()); MINI_DAY_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.mdtp_day_number_size); MONTH_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.mdtp_month_label_size); @@ -300,6 +300,7 @@ protected void initView() { mMonthTitlePaint.setColor(mDayTextColor); mMonthTitlePaint.setTextAlign(Align.CENTER); mMonthTitlePaint.setStyle(Style.FILL); + mMonthTitlePaint.setTextLocale(mController.getLocale()); mSelectedCirclePaint = new Paint(); mSelectedCirclePaint.setFakeBoldText(true); @@ -313,10 +314,11 @@ 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); + mMonthDayLabelPaint.setTextLocale(mController.getLocale()); mMonthNumPaint = new Paint(); mMonthNumPaint.setAntiAlias(true); @@ -324,6 +326,7 @@ protected void initView() { mMonthNumPaint.setStyle(Style.FILL); mMonthNumPaint.setTextAlign(Align.CENTER); mMonthNumPaint.setFakeBoldText(false); + mMonthNumPaint.setTextLocale(mController.getLocale()); } @Override @@ -343,7 +346,7 @@ protected void onDraw(Canvas canvas) { * {@link #VIEW_PARAMS_HEIGHT} for more info on parameters. * * @param params A map of the new parameters, see - * {@link #VIEW_PARAMS_HEIGHT} + * {@link #VIEW_PARAMS_HEIGHT} */ public void setMonthParams(HashMap params) { if (!params.containsKey(VIEW_PARAMS_MONTH) && !params.containsKey(VIEW_PARAMS_YEAR)) { @@ -368,7 +371,7 @@ public void setMonthParams(HashMap params) { // Figure out what day today is //final Time today = new Time(Time.getCurrentTimezone()); //today.setToNow(); - final UmmalquraCalendar today = new UmmalquraCalendar(mController.getTimeZone(),Locale.getDefault()); + final UmmalquraCalendar today = new UmmalquraCalendar(mController.getTimeZone(), mController.getLocale()); mHasToday = false; mToday = -1; @@ -382,7 +385,7 @@ public void setMonthParams(HashMap params) { } else { mWeekStart = mCalendar.getFirstDayOfWeek(); } - mNumCells = UmmalquraCalendar.lengthOfMonth(mCalendar.get(UmmalquraCalendar.YEAR),mCalendar.get(UmmalquraCalendar.MONTH)); + mNumCells = UmmalquraCalendar.lengthOfMonth(mCalendar.get(UmmalquraCalendar.YEAR), mCalendar.get(UmmalquraCalendar.MONTH)); // mNumCells = mCalendar.getActualMaximum(UmmalquraCalendar.DAY_OF_MONTH); for (int i = 0; i < mNumCells; i++) { @@ -451,17 +454,18 @@ protected int getMonthHeaderSize() { @NonNull private String getMonthAndYearString() { - Locale locale = Locale.getDefault(); + Locale locale = mController.getLocale(); String pattern = "MMMM yyyy"; - if(Build.VERSION.SDK_INT < 18) pattern = getContext().getResources().getString(R.string.mdtp_date_v1_monthyear); + if (Build.VERSION.SDK_INT < 18) + pattern = getContext().getResources().getString(R.string.mdtp_date_v1_monthyear); else pattern = DateFormat.getBestDateTimePattern(locale, pattern); SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale); formatter.setTimeZone(mController.getTimeZone()); formatter.applyLocalizedPattern(pattern); mStringBuilder.setLength(0); - return mCalendar.getDisplayName(Calendar.MONTH,Calendar.LONG,locale)+" "+mCalendar.get(Calendar.YEAR); + return mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, locale) + " " + mCalendar.get(Calendar.YEAR); } protected void drawMonthTitle(Canvas canvas) { @@ -496,14 +500,14 @@ protected void drawMonthNums(Canvas canvas) { final float dayWidthHalf = (mWidth - mEdgePadding * 2) / (mNumDays * 2.0f); int j = findDayOffset(); for (int dayNumber = 1; dayNumber <= mNumCells; dayNumber++) { - final int x = (int)((2 * j + 1) * dayWidthHalf + mEdgePadding); + final int x = (int) ((2 * j + 1) * dayWidthHalf + mEdgePadding); int yRelativeToDay = (mRowHeight + MINI_DAY_NUMBER_TEXT_SIZE) / 2 - DAY_SEPARATOR_WIDTH; - final int startX = (int)(x - dayWidthHalf); - final int stopX = (int)(x + dayWidthHalf); - final int startY = (int)(y - yRelativeToDay); - final int stopY = (int)(startY + mRowHeight); + final int startX = (int) (x - dayWidthHalf); + final int stopX = (int) (x + dayWidthHalf); + final int startY = (int) (y - yRelativeToDay); + final int stopY = (int) (startY + mRowHeight); drawMonthDay(canvas, mYear, mMonth, dayNumber, x, y, startX, stopX, startY, stopY); @@ -518,19 +522,19 @@ protected void drawMonthNums(Canvas canvas) { /** * This method should draw the month day. Implemented by sub-classes to allow customization. * - * @param canvas The canvas to draw on - * @param year The year of this month day + * @param canvas The canvas to draw on + * @param year The year of this month day * @param month The month of this month day - * @param day The day number of this month day - * @param x The default x position to draw the day number - * @param y The default y position to draw the day number - * @param startX The left boundary of the day number rect + * @param day The day number of this month day + * @param x The default x position to draw the day number + * @param y The default y position to draw the day number + * @param startX The left boundary of the day number rect * @param stopX The right boundary of the day number rect - * @param startY The top boundary of the day number rect + * @param startY The top boundary of the day number rect * @param stopY The bottom boundary of the day number rect */ public abstract void drawMonthDay(Canvas canvas, int year, int month, int day, - int x, int y, int startX, int stopX, int startY, int stopY); + int x, int y, int startX, int stopX, int startY, int stopY); protected int findDayOffset() { return (mDayOfWeekStart < mWeekStart ? (mDayOfWeekStart + mNumDays) : mDayOfWeekStart) @@ -609,30 +613,30 @@ protected boolean isHighlighted(int year, int month, int day) { /** * Return a 1 or 2 letter String for use as a weekday label + * * @param day The day for which to generate a label * @return The weekday label */ private String getWeekDayLabel(UmmalquraCalendar day) { - Locale locale = Locale.getDefault(); + Locale locale = mController.getLocale(); // Localised short version of the string is not available on API < 18 - if(Build.VERSION.SDK_INT < 18) { + if (Build.VERSION.SDK_INT < 18) { String dayName = new SimpleDateFormat("E", locale).format(day.getTime()); String dayLabel = dayName.toUpperCase(locale).substring(0, 1); // Chinese labels should be fetched right to left if (locale.equals(Locale.CHINA) || locale.equals(Locale.CHINESE) || locale.equals(Locale.SIMPLIFIED_CHINESE) || locale.equals(Locale.TRADITIONAL_CHINESE)) { int len = dayName.length(); - dayLabel = dayName.substring(len -1, len); + dayLabel = dayName.substring(len - 1, len); } // Most hebrew labels should select the second to last character if (locale.getLanguage().equals("he") || locale.getLanguage().equals("iw")) { - if(mDayLabelCalendar.get(UmmalquraCalendar.DAY_OF_WEEK) != UmmalquraCalendar.SATURDAY) { + if (mDayLabelCalendar.get(UmmalquraCalendar.DAY_OF_WEEK) != UmmalquraCalendar.SATURDAY) { int len = dayName.length(); dayLabel = dayName.substring(len - 2, len - 1); - } - else { + } else { // I know this is duplication, but it makes the code easier to grok by // having all hebrew code in the same block dayLabel = dayName.toUpperCase(locale).substring(0, 1); @@ -641,7 +645,7 @@ private String getWeekDayLabel(UmmalquraCalendar day) { // Catalan labels should be two digits in lowercase if (locale.getLanguage().equals("ca")) - dayLabel = dayName.toLowerCase().substring(0,2); + dayLabel = dayName.toLowerCase().substring(0, 2); // Correct single character label in Spanish is X if (locale.getLanguage().equals("es") && day.get(UmmalquraCalendar.DAY_OF_WEEK) == UmmalquraCalendar.WEDNESDAY) @@ -655,7 +659,7 @@ private String getWeekDayLabel(UmmalquraCalendar day) { /** * @return The date that has accessibility focus, or {@code null} if no date - * has focus + * has focus */ public CalendarDay getAccessibilityFocus() { final int day = mTouchHelper.getFocusedVirtualView(); @@ -678,7 +682,7 @@ public void clearAccessibilityFocus() { * * @param day The date which should receive focus * @return {@code false} if the date is not valid for this month view, or - * {@code true} if the date received focus + * {@code true} if the date received focus */ public boolean restoreAccessibilityFocus(CalendarDay day) { if ((day.year != mYear) || (day.month != mMonth) || (day.day > mNumCells)) { @@ -696,7 +700,7 @@ protected class MonthViewTouchHelper extends ExploreByTouchHelper { private static final String DATE_FORMAT = "dd MMMM yyyy"; private final Rect mTempRect = new Rect(); - private final UmmalquraCalendar mTempCalendar = new UmmalquraCalendar(mController.getTimeZone(),Locale.getDefault()); + private final UmmalquraCalendar mTempCalendar = new UmmalquraCalendar(mController.getTimeZone(), mController.getLocale()); public MonthViewTouchHelper(View host) { super(host); @@ -740,7 +744,7 @@ protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEve @Override protected void onPopulateNodeForVirtualView(int virtualViewId, - AccessibilityNodeInfoCompat node) { + AccessibilityNodeInfoCompat node) { getItemBounds(virtualViewId, mTempRect); node.setContentDescription(getItemDescription(virtualViewId)); @@ -755,7 +759,7 @@ protected void onPopulateNodeForVirtualView(int virtualViewId, @Override protected boolean onPerformActionForVirtualView(int virtualViewId, int action, - Bundle arguments) { + Bundle arguments) { switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: onDayClick(virtualViewId); @@ -768,7 +772,7 @@ protected boolean onPerformActionForVirtualView(int virtualViewId, int action, /** * Calculates the bounding rectangle of a given time object. * - * @param day The day to calculate bounds for + * @param day The day to calculate bounds for * @param rect The rectangle in which to store the bounds */ protected void getItemBounds(int day, Rect rect) { diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/YearPickerView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/YearPickerView.java index 2b75155..58616ee 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/YearPickerView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/date/hijri/YearPickerView.java @@ -130,7 +130,7 @@ public View getView(int position, View convertView, ViewGroup parent) { } int year = mMinYear + position; boolean selected = mController.getSelectedDay().year == year; - v.setText(String.valueOf(year)); + v.setText(String.format(mController.getLocale(),"%d", year)); v.drawIndicator(selected); v.requestLayout(); if (selected) { diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/time/AmPmCirclesView.java b/library/src/main/java/net/alhazmy13/hijridatepicker/time/AmPmCirclesView.java index aa8d827..7049be6 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/time/AmPmCirclesView.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/time/AmPmCirclesView.java @@ -30,6 +30,7 @@ import net.alhazmy13.hijridatepicker.Utils; import java.text.DateFormatSymbols; +import java.util.Locale; /** * Draw the two smaller AM and PM circles next to where the larger circle will be. @@ -73,7 +74,7 @@ public AmPmCirclesView(Context context) { mIsInitialized = false; } - public void initialize(Context context, TimePickerController controller, int amOrPm) { + public void initialize(Context context, Locale locale, TimePickerController controller, int amOrPm) { if (mIsInitialized) { Log.e(TAG, "AmPmCirclesView may only be initialized once."); return; @@ -107,7 +108,7 @@ public void initialize(Context context, TimePickerController controller, int amO Float.parseFloat(res.getString(R.string.mdtp_circle_radius_multiplier)); mAmPmCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.mdtp_ampm_circle_radius_multiplier)); - String[] amPmTexts = new DateFormatSymbols().getAmPmStrings(); + String[] amPmTexts = new DateFormatSymbols(locale).getAmPmStrings(); mAmText = amPmTexts[0]; mPmText = amPmTexts[1]; @@ -136,16 +137,16 @@ public int getIsTouchingAmOrPm(float xCoord, float yCoord) { return -1; } - int squaredYDistance = (int) ((yCoord - mAmPmYCenter)*(yCoord - mAmPmYCenter)); + int squaredYDistance = (int) ((yCoord - mAmPmYCenter) * (yCoord - mAmPmYCenter)); int distanceToAmCenter = - (int) Math.sqrt((xCoord - mAmXCenter)*(xCoord - mAmXCenter) + squaredYDistance); + (int) Math.sqrt((xCoord - mAmXCenter) * (xCoord - mAmXCenter) + squaredYDistance); if (distanceToAmCenter <= mAmPmCircleRadius && !mAmDisabled) { return AM; } int distanceToPmCenter = - (int) Math.sqrt((xCoord - mPmXCenter)*(xCoord - mPmXCenter) + squaredYDistance); + (int) Math.sqrt((xCoord - mPmXCenter) * (xCoord - mPmXCenter) + squaredYDistance); if (distanceToPmCenter <= mAmPmCircleRadius && !mPmDisabled) { return PM; } @@ -167,7 +168,7 @@ public void onDraw(Canvas canvas) { int circleRadius = (int) (Math.min(layoutXCenter, layoutYCenter) * mCircleRadiusMultiplier); mAmPmCircleRadius = (int) (circleRadius * mAmPmCircleRadiusMultiplier); - layoutYCenter += mAmPmCircleRadius*0.75; + layoutYCenter += mAmPmCircleRadius * 0.75; int textSize = mAmPmCircleRadius * 3 / 4; mPaint.setTextSize(textSize); diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/time/RadialPickerLayout.java b/library/src/main/java/net/alhazmy13/hijridatepicker/time/RadialPickerLayout.java index 0906233..9970ef5 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/time/RadialPickerLayout.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/time/RadialPickerLayout.java @@ -98,7 +98,9 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { public interface OnValueSelectedListener { void onValueSelected(Timepoint newTime); + void enablePicker(); + void advancePicker(int index); } @@ -156,12 +158,13 @@ public void setOnValueSelectedListener(OnValueSelectedListener listener) { /** * Initialize the Layout with starting values. - * @param context A context needed to inflate resources - * @param initialTime The initial selection of the Timepicker + * + * @param context A context needed to inflate resources + * @param initialTime The initial selection of the Timepicker * @param is24HourMode Indicates whether we should render in 24hour mode or with AM/PM selectors */ - public void initialize(Context context, TimePickerController timePickerController, - Timepoint initialTime, boolean is24HourMode) { + public void initialize(Context context, Locale locale, TimePickerController timePickerController, + Timepoint initialTime, boolean is24HourMode) { if (mTimeInitialized) { Log.e(TAG, "Time has already been initialized."); return; @@ -174,7 +177,7 @@ public void initialize(Context context, TimePickerController timePickerControlle mCircleView.initialize(context, mController); mCircleView.invalidate(); if (!mIs24HourMode && mController.getVersion() == TimePickerDialog.Version.VERSION_1) { - mAmPmCirclesView.initialize(context, mController, initialTime.isAM() ? AM : PM); + mAmPmCirclesView.initialize(context, locale, mController, initialTime.isAM() ? AM : PM); mAmPmCirclesView.invalidate(); } @@ -197,8 +200,8 @@ public boolean isValidSelection(int selection) { @Override public boolean isValidSelection(int selection) { Timepoint newTime = new Timepoint(selection, mCurrentTime.getMinute(), mCurrentTime.getSecond()); - if(!mIs24HourMode && getIsCurrentlyAmOrPm() == PM) newTime.setPM(); - if(!mIs24HourMode && getIsCurrentlyAmOrPm() == AM) newTime.setAM(); + if (!mIs24HourMode && getIsCurrentlyAmOrPm() == PM) newTime.setPM(); + if (!mIs24HourMode && getIsCurrentlyAmOrPm() == AM) newTime.setAM(); return !mController.isOutOfRange(newTime, HOUR_INDEX); } }; @@ -213,10 +216,10 @@ public boolean isValidSelection(int selection) { String[] minutesTexts = new String[12]; String[] secondsTexts = new String[12]; for (int i = 0; i < 12; i++) { - hoursTexts[i] = is24HourMode? - String.format(Locale.getDefault(), "%02d", hours_24[i]) : String.format(Locale.getDefault(), "%d", hours[i]); - innerHoursTexts[i] = String.format(Locale.getDefault(), "%d", hours[i]); - minutesTexts[i] = String.format(Locale.getDefault(), "%02d", minutes[i]); + hoursTexts[i] = is24HourMode ? + String.format(locale, "%02d", hours_24[i]) : String.format(locale, "%d", hours[i]); + innerHoursTexts[i] = String.format(locale, "%d", hours[i]); + minutesTexts[i] = String.format(locale, "%02d", minutes[i]); secondsTexts[i] = String.format(Locale.getDefault(), "%02d", seconds[i]); } mHourRadialTextsView.initialize(context, @@ -260,6 +263,7 @@ private void setItem(int index, Timepoint time) { /** * Check if a given hour appears in the outer circle or the inner circle + * * @return true if the hour is in the inner circle, false if it's in the outer circle. */ private boolean isHourInnerCircle(int hourOfDay) { @@ -289,7 +293,7 @@ public Timepoint getTime() { */ private int getCurrentlyShowingValue() { int currentIndex = getCurrentItemShowing(); - switch(currentIndex) { + switch (currentIndex) { case HOUR_INDEX: return mCurrentTime.getHour(); case MINUTE_INDEX: @@ -312,14 +316,15 @@ public int getIsCurrentlyAmOrPm() { /** * Set the internal value as either AM or PM, and update the AM/PM circle displays. + * * @param amOrPm Integer representing AM of PM (use the supplied constants) */ public void setAmOrPm(int amOrPm) { mAmPmCirclesView.setAmOrPm(amOrPm); mAmPmCirclesView.invalidate(); Timepoint newSelection = new Timepoint(mCurrentTime); - if(amOrPm == AM) newSelection.setAM(); - else if(amOrPm == PM) newSelection.setPM(); + if (amOrPm == AM) newSelection.setAM(); + else if (amOrPm == PM) newSelection.setPM(); newSelection = roundToValidTime(newSelection, HOUR_INDEX); reselectSelector(newSelection, false, HOUR_INDEX); mCurrentTime = newSelection; @@ -399,10 +404,11 @@ private int snapPrefer30s(int degrees) { /** * Returns mapping of any input degrees (0 to 360) to one of 12 visible output degrees (all * multiples of 30), where the input will be "snapped" to the closest visible degrees. - * @param degrees The input degrees + * + * @param degrees The input degrees * @param forceHigherOrLower The output may be forced to either the higher or lower step, or may - * be allowed to snap to whichever is closer. Use 1 to force strictly higher, -1 to force - * strictly lower, and 0 to snap to the closer one. + * be allowed to snap to whichever is closer. Use 1 to force strictly higher, -1 to force + * strictly lower, and 0 to snap to the closer one. * @return output degrees, will be a multiple of 30 */ private static int snapOnly30s(int degrees, int forceHigherOrLower) { @@ -428,12 +434,13 @@ private static int snapOnly30s(int degrees, int forceHigherOrLower) { /** * Snap the input to a selectable value - * @param newSelection Timepoint - Time which should be rounded + * + * @param newSelection Timepoint - Time which should be rounded * @param currentItemShowing int - The index of the current view * @return Timepoint - the rounded value */ private Timepoint roundToValidTime(Timepoint newSelection, int currentItemShowing) { - switch(currentItemShowing) { + switch (currentItemShowing) { case HOUR_INDEX: newSelection = mController.roundToNearest(newSelection, Timepoint.TYPE.HOUR); break; @@ -453,58 +460,59 @@ private Timepoint roundToValidTime(Timepoint newSelection, int currentItemShowin * For the currently showing view (either hours, minutes or seconds), re-calculate the position * for the selector, and redraw it at that position. The text representing the currently * selected value will be redrawn if required. + * * @param newSelection Timpoint - Time which should be selected. * @param forceDrawDot The dot in the circle will generally only be shown when the selection - * @param index The picker to use as a reference. Will be getCurrentItemShow() except when AM/PM is changed - * is on non-visible values, but use this to force the dot to be shown. + * @param index The picker to use as a reference. Will be getCurrentItemShow() except when AM/PM is changed + * is on non-visible values, but use this to force the dot to be shown. */ private void reselectSelector(Timepoint newSelection, boolean forceDrawDot, int index) { - switch(index) { + switch (index) { case HOUR_INDEX: // The selection might have changed, recalculate the degrees and innerCircle values int hour = newSelection.getHour(); boolean isInnerCircle = isHourInnerCircle(hour); - int degrees = (hour%12)*360/12; - if(!mIs24HourMode) hour = hour%12; - if(!mIs24HourMode && hour == 0) hour += 12; + int degrees = (hour % 12) * 360 / 12; + if (!mIs24HourMode) hour = hour % 12; + if (!mIs24HourMode && hour == 0) hour += 12; mHourRadialSelectorView.setSelection(degrees, isInnerCircle, forceDrawDot); mHourRadialTextsView.setSelection(hour); // If we rounded the minutes, reposition the minuteSelector too. - if(newSelection.getMinute() != mCurrentTime.getMinute()) { - int minDegrees = newSelection.getMinute()*360/60; + if (newSelection.getMinute() != mCurrentTime.getMinute()) { + int minDegrees = newSelection.getMinute() * 360 / 60; mMinuteRadialSelectorView.setSelection(minDegrees, isInnerCircle, forceDrawDot); mMinuteRadialTextsView.setSelection(newSelection.getMinute()); } // If we rounded the seconds, reposition the secondSelector too. - if(newSelection.getSecond() != mCurrentTime.getSecond()) { - int secDegrees = newSelection.getSecond()*360/60; + if (newSelection.getSecond() != mCurrentTime.getSecond()) { + int secDegrees = newSelection.getSecond() * 360 / 60; mSecondRadialSelectorView.setSelection(secDegrees, isInnerCircle, forceDrawDot); mSecondRadialTextsView.setSelection(newSelection.getSecond()); } break; case MINUTE_INDEX: // The selection might have changed, recalculate the degrees - degrees = newSelection.getMinute()*360/60; + degrees = newSelection.getMinute() * 360 / 60; mMinuteRadialSelectorView.setSelection(degrees, false, forceDrawDot); mMinuteRadialTextsView.setSelection(newSelection.getMinute()); // If we rounded the seconds, reposition the secondSelector too. - if(newSelection.getSecond() != mCurrentTime.getSecond()) { - int secDegrees = newSelection.getSecond()*360/60; + if (newSelection.getSecond() != mCurrentTime.getSecond()) { + int secDegrees = newSelection.getSecond() * 360 / 60; mSecondRadialSelectorView.setSelection(secDegrees, false, forceDrawDot); mSecondRadialTextsView.setSelection(newSelection.getSecond()); } break; case SECOND_INDEX: // The selection might have changed, recalculate the degrees - degrees = newSelection.getSecond()*360/60; + degrees = newSelection.getSecond() * 360 / 60; mSecondRadialSelectorView.setSelection(degrees, false, forceDrawDot); mSecondRadialTextsView.setSelection(newSelection.getSecond()); } // Invalidate the currently showing picker to force a redraw - switch(getCurrentItemShowing()) { + switch (getCurrentItemShowing()) { case HOUR_INDEX: mHourRadialSelectorView.invalidate(); mHourRadialTextsView.invalidate(); @@ -566,11 +574,11 @@ private Timepoint getTimeFromDegrees(int degrees, boolean isInnerCircle, boolean } Timepoint newSelection; - switch(currentShowing) { + switch (currentShowing) { case HOUR_INDEX: int hour = value; - if(!mIs24HourMode && getIsCurrentlyAmOrPm() == PM && degrees != 360) hour += 12; - if(!mIs24HourMode && getIsCurrentlyAmOrPm() == AM && degrees == 360) hour = 0; + if (!mIs24HourMode && getIsCurrentlyAmOrPm() == PM && degrees != 360) hour += 12; + if (!mIs24HourMode && getIsCurrentlyAmOrPm() == AM && degrees == 360) hour = 0; newSelection = new Timepoint(hour, mCurrentTime.getMinute(), mCurrentTime.getSecond()); break; case MINUTE_INDEX: @@ -589,18 +597,19 @@ private Timepoint getTimeFromDegrees(int degrees, boolean isInnerCircle, boolean /** * Calculate the degrees within the circle that corresponds to the specified coordinates, if * the coordinates are within the range that will trigger a selection. - * @param pointX The x coordinate. - * @param pointY The y coordinate. - * @param forceLegal Force the selection to be legal, regardless of how far the coordinates are - * from the actual numbers. + * + * @param pointX The x coordinate. + * @param pointY The y coordinate. + * @param forceLegal Force the selection to be legal, regardless of how far the coordinates are + * from the actual numbers. * @param isInnerCircle If the selection may be in the inner circle, pass in a size-1 boolean - * array here, inside which the value will be true if the selection is in the inner circle, - * and false if in the outer circle. + * array here, inside which the value will be true if the selection is in the inner circle, + * and false if in the outer circle. * @return Degrees from 0 to 360, if the selection was within the legal range. -1 if not. */ private int getDegreesFromCoords(float pointX, float pointY, boolean forceLegal, - final Boolean[] isInnerCircle) { - switch(getCurrentItemShowing()) { + final Boolean[] isInnerCircle) { + switch (getCurrentItemShowing()) { case HOUR_INDEX: return mHourRadialSelectorView.getDegreesFromCoords( pointX, pointY, forceLegal, isInnerCircle); @@ -628,11 +637,12 @@ public int getCurrentItemShowing() { /** * Set either seconds, minutes or hours as showing. + * * @param animate True to animate the transition, false to show with no animation. */ public void setCurrentItemShowing(int index, boolean animate) { if (index != HOUR_INDEX && index != MINUTE_INDEX && index != SECOND_INDEX) { - Log.e(TAG, "TimePicker does not support view at index "+index); + Log.e(TAG, "TimePicker does not support view at index " + index); return; } @@ -647,7 +657,7 @@ public void setCurrentItemShowing(int index, boolean animate) { anims[1] = mHourRadialSelectorView.getDisappearAnimator(); anims[2] = mMinuteRadialTextsView.getReappearAnimator(); anims[3] = mMinuteRadialSelectorView.getReappearAnimator(); - } else if (index == HOUR_INDEX && lastIndex == MINUTE_INDEX){ + } else if (index == HOUR_INDEX && lastIndex == MINUTE_INDEX) { anims[0] = mHourRadialTextsView.getReappearAnimator(); anims[1] = mHourRadialSelectorView.getReappearAnimator(); anims[2] = mMinuteRadialTextsView.getDisappearAnimator(); @@ -675,7 +685,7 @@ public void setCurrentItemShowing(int index, boolean animate) { } if (anims[0] != null && anims[1] != null && anims[2] != null && - anims[3] != null) { + anims[3] != null) { if (mTransition != null && mTransition.isRunning()) { mTransition.end(); } @@ -711,7 +721,7 @@ public boolean onTouch(View v, MotionEvent event) { final Boolean[] isInnerCircle = new Boolean[1]; isInnerCircle[0] = false; - switch(event.getAction()) { + switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!mInputEnabled) { return true; @@ -748,7 +758,8 @@ public void run() { // Calculate the degrees that is currently being touched. mDownDegrees = getDegreesFromCoords(eventX, eventY, forceLegal, isInnerCircle); Timepoint selectedTime = getTimeFromDegrees(mDownDegrees, isInnerCircle[0], false); - if(mController.isOutOfRange(selectedTime, getCurrentItemShowing())) mDownDegrees = -1; + if (mController.isOutOfRange(selectedTime, getCurrentItemShowing())) + mDownDegrees = -1; if (mDownDegrees != -1) { // If it's a legal touch, set that number as "selected" after the // TAP_TIMEOUT in case the user moves their finger quickly. @@ -807,7 +818,7 @@ public void run() { mHandler.removeCallbacksAndMessages(null); degrees = getDegreesFromCoords(eventX, eventY, true, isInnerCircle); if (degrees != -1) { - switch(getCurrentItemShowing()) { + switch (getCurrentItemShowing()) { case HOUR_INDEX: value = mController.roundToNearest( getTimeFromDegrees(degrees, isInnerCircle[0], false), @@ -856,8 +867,8 @@ public void run() { mAmPmCirclesView.setAmOrPm(isTouchingAmOrPm); if (getIsCurrentlyAmOrPm() != isTouchingAmOrPm) { Timepoint newSelection = new Timepoint(mCurrentTime); - if(mIsTouchingAmOrPm == AM) newSelection.setAM(); - else if(mIsTouchingAmOrPm == PM) newSelection.setPM(); + if (mIsTouchingAmOrPm == AM) newSelection.setAM(); + else if (mIsTouchingAmOrPm == PM) newSelection.setPM(); newSelection = roundToValidTime(newSelection, HOUR_INDEX); reselectSelector(newSelection, false, HOUR_INDEX); mCurrentTime = newSelection; @@ -900,7 +911,7 @@ public boolean trySettingInputEnabled(boolean inputEnabled) { } mInputEnabled = inputEnabled; - mGrayBox.setVisibility(inputEnabled? View.INVISIBLE : View.VISIBLE); + mGrayBox.setVisibility(inputEnabled ? View.INVISIBLE : View.VISIBLE); return true; } @@ -915,8 +926,7 @@ public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo inf if (Build.VERSION.SDK_INT >= 21) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); - } - else if (Build.VERSION.SDK_INT >= 16) { + } else if (Build.VERSION.SDK_INT >= 16) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); } else { @@ -1011,7 +1021,7 @@ public boolean performAccessibilityAction(int action, Bundle arguments) { } Timepoint newSelection; - switch(currentItemShowing) { + switch (currentItemShowing) { case HOUR_INDEX: newSelection = new Timepoint( value, diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/time/TimePickerDialog.java b/library/src/main/java/net/alhazmy13/hijridatepicker/time/TimePickerDialog.java index f4fe1cf..e87419c 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/time/TimePickerDialog.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/time/TimePickerDialog.java @@ -93,6 +93,7 @@ public enum Version { private static final String KEY_CANCEL_STRING = "cancel_string"; private static final String KEY_CANCEL_COLOR = "cancel_color"; private static final String KEY_VERSION = "version"; + private static final String KEY_LOCALE = "locale"; public static final int HOUR_INDEX = 0; public static final int MINUTE_INDEX = 1; @@ -159,6 +160,8 @@ public enum Version { private int mAmKeyCode; private int mPmKeyCode; + private Locale mLocale = Locale.getDefault(); + // Accessibility strings. private String mHourPickerDescription; private String mSelectHours; @@ -174,10 +177,10 @@ public enum Version { public interface OnTimeSetListener { /** - * @param view The view associated with this listener. + * @param view The view associated with this listener. * @param hourOfDay The hour that was set. - * @param minute The minute that was set. - * @param second The second that was set + * @param minute The minute that was set. + * @param second The second that was set */ void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second); } @@ -187,19 +190,19 @@ public TimePickerDialog() { } public static TimePickerDialog newInstance(OnTimeSetListener callback, - int hourOfDay, int minute, int second, boolean is24HourMode) { + int hourOfDay, int minute, int second, boolean is24HourMode) { TimePickerDialog ret = new TimePickerDialog(); ret.initialize(callback, hourOfDay, minute, second, is24HourMode); return ret; } public static TimePickerDialog newInstance(OnTimeSetListener callback, - int hourOfDay, int minute, boolean is24HourMode) { + int hourOfDay, int minute, boolean is24HourMode) { return TimePickerDialog.newInstance(callback, hourOfDay, minute, 0, is24HourMode); } public void initialize(OnTimeSetListener callback, - int hourOfDay, int minute, int second, boolean is24HourMode) { + int hourOfDay, int minute, int second, boolean is24HourMode) { mCallback = callback; mInitialTime = new Timepoint(hourOfDay, minute, second); @@ -241,6 +244,7 @@ public void setThemeDark(boolean dark) { /** * Set the accent color of this dialog + * * @param color the accent color you want */ @SuppressWarnings("unused") @@ -250,6 +254,7 @@ public void setAccentColor(String color) { /** * Set the accent color of this dialog + * * @param color the accent color you want */ public void setAccentColor(@ColorInt int color) { @@ -258,6 +263,7 @@ public void setAccentColor(@ColorInt int color) { /** * Set the text color of the OK button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -267,6 +273,7 @@ public void setOkColor(String color) { /** * Set the text color of the OK button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -276,6 +283,7 @@ public void setOkColor(@ColorInt int color) { /** * Set the text color of the Cancel button + * * @param color the color you want */ @SuppressWarnings("unused") @@ -285,11 +293,12 @@ public void setCancelColor(String color) { /** * Set the text color of the Cancel button + * * @param color the color you want */ @SuppressWarnings("unused") public void setCancelColor(@ColorInt int color) { - mCancelColor= Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)); + mCancelColor = Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)); } @Override @@ -309,6 +318,7 @@ public int getAccentColor() { /** * Set whether the device should vibrate when touching fields + * * @param vibrate true if the device should vibrate when touching a field */ public void vibrate(boolean vibrate) { @@ -317,6 +327,7 @@ public void vibrate(boolean vibrate) { /** * Set whether the picker should dismiss itself when it's pausing or whether it should try to survive an orientation change + * * @param dismissOnPause true if the picker should dismiss itself */ public void dismissOnPause(boolean dismissOnPause) { @@ -326,6 +337,7 @@ public void dismissOnPause(boolean dismissOnPause) { /** * Set whether an additional picker for seconds should be shown * Will enable minutes picker as well if seconds picker should be shown + * * @param enableSeconds true if the seconds picker should be shown */ public void enableSeconds(boolean enableSeconds) { @@ -336,6 +348,7 @@ public void enableSeconds(boolean enableSeconds) { /** * Set whether the picker for minutes should be shown * Will disable seconds if minutes are disbled + * * @param enableMinutes true if minutes picker should be shown */ @SuppressWarnings("unused") @@ -343,13 +356,14 @@ public void enableMinutes(boolean enableMinutes) { if (!enableMinutes) mEnableSeconds = false; mEnableMinutes = enableMinutes; } + @SuppressWarnings("unused") public void setMinTime(int hour, int minute, int second) { setMinTime(new Timepoint(hour, minute, second)); } public void setMinTime(Timepoint minTime) { - if(mMaxTime != null && minTime.compareTo(mMaxTime) > 0) + if (mMaxTime != null && minTime.compareTo(mMaxTime) > 0) throw new IllegalArgumentException("Minimum time must be smaller than the maximum time"); mMinTime = minTime; } @@ -360,7 +374,7 @@ public void setMaxTime(int hour, int minute, int second) { } public void setMaxTime(Timepoint maxTime) { - if(mMinTime != null && maxTime.compareTo(mMinTime) < 0) + if (mMinTime != null && maxTime.compareTo(mMinTime) < 0) throw new IllegalArgumentException("Maximum time must be greater than the minimum time"); mMaxTime = maxTime; } @@ -375,13 +389,14 @@ public void setSelectableTimes(Timepoint[] selectableTimes) { * Set the interval for selectable times in the TimePickerDialog * This is a convenience wrapper around setSelectableTimes * The interval for all three time components can be set independently - * @param hourInterval The interval between 2 selectable hours ([1,24]) + * + * @param hourInterval The interval between 2 selectable hours ([1,24]) * @param minuteInterval The interval between 2 selectable minutes ([1,60]) * @param secondInterval The interval between 2 selectable seconds ([1,60]) */ - public void setTimeInterval(@IntRange(from=1, to=24) int hourInterval, - @IntRange(from=1, to=60) int minuteInterval, - @IntRange(from=1, to=60) int secondInterval) { + public void setTimeInterval(@IntRange(from = 1, to = 24) int hourInterval, + @IntRange(from = 1, to = 60) int minuteInterval, + @IntRange(from = 1, to = 60) int secondInterval) { List timepoints = new ArrayList<>(); int hour = 0; @@ -404,11 +419,12 @@ public void setTimeInterval(@IntRange(from=1, to=24) int hourInterval, * Set the interval for selectable times in the TimePickerDialog * This is a convenience wrapper around setSelectableTimes * The interval for all three time components can be set independently - * @param hourInterval The interval between 2 selectable hours ([1,24]) + * + * @param hourInterval The interval between 2 selectable hours ([1,24]) * @param minuteInterval The interval between 2 selectable minutes ([1,60]) */ - public void setTimeInterval(@IntRange(from=1, to=24) int hourInterval, - @IntRange(from=1, to=60) int minuteInterval) { + public void setTimeInterval(@IntRange(from = 1, to = 24) int hourInterval, + @IntRange(from = 1, to = 60) int minuteInterval) { setTimeInterval(hourInterval, minuteInterval, 1); } @@ -416,10 +432,11 @@ public void setTimeInterval(@IntRange(from=1, to=24) int hourInterval, * Set the interval for selectable times in the TimePickerDialog * This is a convenience wrapper around setSelectableTimes * The interval for all three time components can be set independently + * * @param hourInterval The interval between 2 selectable hours ([1,24]) */ @SuppressWarnings("unused") - public void setTimeInterval(@IntRange(from=1, to=24) int hourInterval) { + public void setTimeInterval(@IntRange(from = 1, to = 24) int hourInterval) { setTimeInterval(hourInterval, 1); } @@ -427,6 +444,10 @@ public void setOnTimeSetListener(OnTimeSetListener callback) { mCallback = callback; } + public void setLocale(Locale locale) { + mLocale = locale; + } + public void setOnCancelListener(DialogInterface.OnCancelListener onCancelListener) { mOnCancelListener = onCancelListener; } @@ -448,6 +469,7 @@ public void setStartTime(int hourOfDay, int minute) { /** * Set the label for the Ok button (max 12 characters) + * * @param okString A literal String to be used as the Ok button label */ @SuppressWarnings("unused") @@ -457,6 +479,7 @@ public void setOkText(String okString) { /** * Set the label for the Ok button (max 12 characters) + * * @param okResid A resource ID to be used as the Ok button label */ @SuppressWarnings("unused") @@ -467,6 +490,7 @@ public void setOkText(@StringRes int okResid) { /** * Set the label for the Cancel button (max 12 characters) + * * @param cancelString A literal String to be used as the Cancel button label */ @SuppressWarnings("unused") @@ -476,6 +500,7 @@ public void setCancelText(String cancelString) { /** * Set the label for the Cancel button (max 12 characters) + * * @param cancelResid A resource ID to be used as the Cancel button label */ @SuppressWarnings("unused") @@ -486,6 +511,7 @@ public void setCancelText(@StringRes int cancelResid) { /** * Set which layout version the picker should use + * * @param version The version to use */ public void setVersion(Version version) { @@ -501,7 +527,7 @@ public Version getVersion() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null && savedInstanceState.containsKey(KEY_INITIAL_TIME) - && savedInstanceState.containsKey(KEY_IS_24_HOUR_VIEW)) { + && savedInstanceState.containsKey(KEY_IS_24_HOUR_VIEW)) { mInitialTime = savedInstanceState.getParcelable(KEY_INITIAL_TIME); mIs24HourMode = savedInstanceState.getBoolean(KEY_IS_24_HOUR_VIEW); mInKbMode = savedInstanceState.getBoolean(KEY_IN_KB_MODE); @@ -511,7 +537,7 @@ public void onCreate(Bundle savedInstanceState) { mAccentColor = savedInstanceState.getInt(KEY_ACCENT); mVibrate = savedInstanceState.getBoolean(KEY_VIBRATE); mDismissOnPause = savedInstanceState.getBoolean(KEY_DISMISS); - mSelectableTimes = (Timepoint[])savedInstanceState.getParcelableArray(KEY_SELECTABLE_TIMES); + mSelectableTimes = (Timepoint[]) savedInstanceState.getParcelableArray(KEY_SELECTABLE_TIMES); mMinTime = savedInstanceState.getParcelable(KEY_MIN_TIME); mMaxTime = savedInstanceState.getParcelable(KEY_MAX_TIME); mEnableSeconds = savedInstanceState.getBoolean(KEY_ENABLE_SECONDS); @@ -523,15 +549,16 @@ public void onCreate(Bundle savedInstanceState) { mCancelString = savedInstanceState.getString(KEY_CANCEL_STRING); mCancelColor = savedInstanceState.getInt(KEY_CANCEL_COLOR); mVersion = (Version) savedInstanceState.getSerializable(KEY_VERSION); + mLocale = (Locale) savedInstanceState.getSerializable(KEY_LOCALE); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { int viewRes = mVersion == Version.VERSION_1 ? R.layout.hdp_mdtp_time_picker_dialog : R.layout.hdp_mdtp_time_picker_dialog_v2; - View view = inflater.inflate(viewRes, container,false); + View view = inflater.inflate(viewRes, container, false); KeyboardListener keyboardListener = new KeyboardListener(); view.findViewById(R.id.mdtp_time_picker_dialog).setOnKeyListener(keyboardListener); @@ -570,13 +597,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mPmTextView = (TextView) view.findViewById(R.id.mdtp_pm_label); mPmTextView.setOnKeyListener(keyboardListener); mAmPmLayout = view.findViewById(R.id.mdtp_ampm_layout); - String[] amPmTexts = new DateFormatSymbols().getAmPmStrings(); + String[] amPmTexts = new DateFormatSymbols(mLocale).getAmPmStrings(); mAmText = amPmTexts[0]; mPmText = amPmTexts[1]; mHapticFeedbackController = new HapticFeedbackController(getActivity()); - if(mTimePicker != null) { + if (mTimePicker != null) { mInitialTime = new Timepoint(mTimePicker.getHours(), mTimePicker.getMinutes(), mTimePicker.getSeconds()); } @@ -585,7 +612,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mTimePicker = (RadialPickerLayout) view.findViewById(R.id.mdtp_time_picker); mTimePicker.setOnValueSelectedListener(this); mTimePicker.setOnKeyListener(keyboardListener); - mTimePicker.initialize(getActivity(), this, mInitialTime, mIs24HourMode); + mTimePicker.initialize(getActivity(), mLocale, this, mInitialTime, mIs24HourMode); int currentItemShowing = HOUR_INDEX; if (savedInstanceState != null && @@ -632,7 +659,7 @@ public void onClick(View v) { }); mOkButton.setOnKeyListener(keyboardListener); mOkButton.setTypeface(TypefaceHelper.get(context, "Roboto-Medium")); - if(mOkString != null) mOkButton.setText(mOkString); + if (mOkString != null) mOkButton.setText(mOkString); else mOkButton.setText(mOkResid); mCancelButton = (Button) view.findViewById(R.id.mdtp_cancel); @@ -644,7 +671,7 @@ public void onClick(View v) { } }); mCancelButton.setTypeface(TypefaceHelper.get(context, "Roboto-Medium")); - if(mCancelString != null) mCancelButton.setText(mCancelString); + if (mCancelString != null) mCancelButton.setText(mCancelString); else mCancelButton.setText(mCancelResid); mCancelButton.setVisibility(isCancelable() ? View.VISIBLE : View.GONE); @@ -668,7 +695,7 @@ public void onClick(View v) { mTimePicker.setAmOrPm(amOrPm); } }; - mAmTextView .setVisibility(View.GONE); + mAmTextView.setVisibility(View.GONE); mPmTextView.setVisibility(View.VISIBLE); mAmPmLayout.setOnClickListener(listener); if (mVersion == Version.VERSION_2) { @@ -781,8 +808,7 @@ public void onClick(View v) { paramsAmPm.addRule(RelativeLayout.BELOW, R.id.mdtp_seconds_space); mAmPmLayout.setLayoutParams(paramsAmPm); } - } - else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { + } else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { // center first separator RelativeLayout.LayoutParams paramsSeparator = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT @@ -800,7 +826,7 @@ else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { if (!mIs24HourMode) { RelativeLayout.LayoutParams paramsAmPm = new RelativeLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT + LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ); paramsAmPm.addRule(RelativeLayout.RIGHT_OF, R.id.mdtp_hour_space); paramsAmPm.addRule(RelativeLayout.ALIGN_BASELINE, R.id.mdtp_hour_space); @@ -856,7 +882,7 @@ else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { TextView timePickerHeader = (TextView) view.findViewById(R.id.mdtp_time_picker_header); if (!mTitle.isEmpty()) { timePickerHeader.setVisibility(TextView.VISIBLE); - timePickerHeader.setText(mTitle.toUpperCase(Locale.getDefault())); + timePickerHeader.setText(mTitle.toUpperCase(mLocale)); } // Set the theme at the end so that the initialize()s above don't counteract the theme. @@ -870,7 +896,7 @@ else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { if (mCancelColor != -1) mCancelButton.setTextColor(mCancelColor); else mCancelButton.setTextColor(mAccentColor); - if(getDialog() == null) { + if (getDialog() == null) { view.findViewById(R.id.mdtp_done_background).setVisibility(View.GONE); } @@ -879,7 +905,7 @@ else if (mIs24HourMode && !mEnableSeconds && mEnableMinutes) { int darkBackgroundColor = ContextCompat.getColor(context, R.color.mdtp_light_gray); int lightGray = ContextCompat.getColor(context, R.color.mdtp_light_gray); - mTimePicker.setBackgroundColor(mThemeDark? lightGray : circleBackground); + mTimePicker.setBackgroundColor(mThemeDark ? lightGray : circleBackground); view.findViewById(R.id.mdtp_time_picker_dialog).setBackgroundColor(mThemeDark ? darkBackgroundColor : backgroundColor); return view; } @@ -912,24 +938,24 @@ public void onResume() { public void onPause() { super.onPause(); mHapticFeedbackController.stop(); - if(mDismissOnPause) dismiss(); + if (mDismissOnPause) dismiss(); } @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); - if(mOnCancelListener != null) mOnCancelListener.onCancel(dialog); + if (mOnCancelListener != null) mOnCancelListener.onCancel(dialog); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); - if(mOnDismissListener != null) mOnDismissListener.onDismiss(dialog); + if (mOnDismissListener != null) mOnDismissListener.onDismiss(dialog); } @Override public void tryVibrate() { - if(mVibrate) mHapticFeedbackController.tryVibrate(); + if (mVibrate) mHapticFeedbackController.tryVibrate(); } private void updateAmPmDisplay(int amOrPm) { @@ -948,7 +974,7 @@ private void updateAmPmDisplay(int amOrPm) { mPmTextView.setText(mAmText); Utils.tryAccessibilityAnnounce(mTimePicker, mAmText); mPmTextView.setContentDescription(mAmText); - } else if (amOrPm == PM){ + } else if (amOrPm == PM) { mPmTextView.setText(mPmText); Utils.tryAccessibilityAnnounce(mTimePicker, mPmText); mPmTextView.setContentDescription(mPmText); @@ -1000,90 +1026,89 @@ public void onValueSelected(Timepoint newValue) { mTimePicker.setContentDescription(mMinutePickerDescription + ": " + newValue.getMinute()); setSecond(newValue.getSecond()); mTimePicker.setContentDescription(mSecondPickerDescription + ": " + newValue.getSecond()); - if(!mIs24HourMode) updateAmPmDisplay(newValue.isAM() ? AM : PM); + if (!mIs24HourMode) updateAmPmDisplay(newValue.isAM() ? AM : PM); } @Override public void advancePicker(int index) { - if(!mAllowAutoAdvance) return; - if(index == HOUR_INDEX && mEnableMinutes) { + if (!mAllowAutoAdvance) return; + if (index == HOUR_INDEX && mEnableMinutes) { setCurrentItemShowing(MINUTE_INDEX, true, true, false); String announcement = mSelectHours + ". " + mTimePicker.getMinutes(); Utils.tryAccessibilityAnnounce(mTimePicker, announcement); - } else if(index == MINUTE_INDEX && mEnableSeconds) { + } else if (index == MINUTE_INDEX && mEnableSeconds) { setCurrentItemShowing(SECOND_INDEX, true, true, false); - String announcement = mSelectMinutes+". " + mTimePicker.getSeconds(); + String announcement = mSelectMinutes + ". " + mTimePicker.getSeconds(); Utils.tryAccessibilityAnnounce(mTimePicker, announcement); } } @Override public void enablePicker() { - if(!isTypedTimeFullyLegal()) mTypedTimes.clear(); + if (!isTypedTimeFullyLegal()) mTypedTimes.clear(); finishKbMode(true); } public boolean isOutOfRange(Timepoint current) { - if(mMinTime != null && mMinTime.compareTo(current) > 0) return true; + if (mMinTime != null && mMinTime.compareTo(current) > 0) return true; - if(mMaxTime != null && mMaxTime.compareTo(current) < 0) return true; + if (mMaxTime != null && mMaxTime.compareTo(current) < 0) return true; - if(mSelectableTimes != null) return !Arrays.asList(mSelectableTimes).contains(current); + if (mSelectableTimes != null) return !Arrays.asList(mSelectableTimes).contains(current); return false; } @Override public boolean isOutOfRange(Timepoint current, int index) { - if(current == null) return false; + if (current == null) return false; - if(index == HOUR_INDEX) { - if(mMinTime != null && mMinTime.getHour() > current.getHour()) return true; + if (index == HOUR_INDEX) { + if (mMinTime != null && mMinTime.getHour() > current.getHour()) return true; - if(mMaxTime != null && mMaxTime.getHour()+1 <= current.getHour()) return true; + if (mMaxTime != null && mMaxTime.getHour() + 1 <= current.getHour()) return true; - if(mSelectableTimes != null) { - for(Timepoint t : mSelectableTimes) { - if(t.getHour() == current.getHour()) return false; + if (mSelectableTimes != null) { + for (Timepoint t : mSelectableTimes) { + if (t.getHour() == current.getHour()) return false; } return true; } return false; - } - else if(index == MINUTE_INDEX) { - if(mMinTime != null) { + } else if (index == MINUTE_INDEX) { + if (mMinTime != null) { Timepoint roundedMin = new Timepoint(mMinTime.getHour(), mMinTime.getMinute()); if (roundedMin.compareTo(current) > 0) return true; } - if(mMaxTime != null) { + if (mMaxTime != null) { Timepoint roundedMax = new Timepoint(mMaxTime.getHour(), mMaxTime.getMinute(), 59); if (roundedMax.compareTo(current) < 0) return true; } - if(mSelectableTimes != null) { - for(Timepoint t : mSelectableTimes) { - if(t.getHour() == current.getHour() && t.getMinute() == current.getMinute()) return false; + if (mSelectableTimes != null) { + for (Timepoint t : mSelectableTimes) { + if (t.getHour() == current.getHour() && t.getMinute() == current.getMinute()) + return false; } return true; } return false; - } - else return isOutOfRange(current); + } else return isOutOfRange(current); } @Override public boolean isAmDisabled() { Timepoint midday = new Timepoint(12); - if(mMinTime != null && mMinTime.compareTo(midday) > 0) return true; + if (mMinTime != null && mMinTime.compareTo(midday) > 0) return true; - if(mSelectableTimes != null) { - for(Timepoint t : mSelectableTimes) if(t.compareTo(midday) < 0) return false; + if (mSelectableTimes != null) { + for (Timepoint t : mSelectableTimes) if (t.compareTo(midday) < 0) return false; return true; } @@ -1094,10 +1119,10 @@ public boolean isAmDisabled() { public boolean isPmDisabled() { Timepoint midday = new Timepoint(12); - if(mMaxTime != null && mMaxTime.compareTo(midday) < 0) return true; + if (mMaxTime != null && mMaxTime.compareTo(midday) < 0) return true; - if(mSelectableTimes != null) { - for(Timepoint t : mSelectableTimes) if(t.compareTo(midday) >= 0) return false; + if (mSelectableTimes != null) { + for (Timepoint t : mSelectableTimes) if (t.compareTo(midday) >= 0) return false; return true; } @@ -1106,6 +1131,7 @@ public boolean isPmDisabled() { /** * Round a given Timepoint to the nearest valid Timepoint + * * @param time Timepoint - The timepoint to round * @return Timepoint - The nearest valid Timepoint */ @@ -1116,19 +1142,20 @@ private Timepoint roundToNearest(@NonNull Timepoint time) { @Override public Timepoint roundToNearest(@NonNull Timepoint time, @Nullable Timepoint.TYPE type) { - if(mMinTime != null && mMinTime.compareTo(time) > 0) return mMinTime; + if (mMinTime != null && mMinTime.compareTo(time) > 0) return mMinTime; - if(mMaxTime != null && mMaxTime.compareTo(time) < 0) return mMaxTime; - if(mSelectableTimes != null) { + if (mMaxTime != null && mMaxTime.compareTo(time) < 0) return mMaxTime; + if (mSelectableTimes != null) { int currentDistance = Integer.MAX_VALUE; Timepoint output = time; - for(Timepoint t : mSelectableTimes) { - Log.d("Timepoing", "" + type + " " + time + " compared to " + t.toString()); + for (Timepoint t : mSelectableTimes) { + Log.d("Timepoing", "" + type + " " + time + " compared to " + t.toString()); // type == null: no restrictions // type == HOUR: do not change the hour if (type == Timepoint.TYPE.HOUR && t.getHour() != time.getHour()) continue; // type == MINUTE: do not change hour or minute - if (type == Timepoint.TYPE.MINUTE && t.getHour() != time.getHour() && t.getMinute() != time.getMinute()) continue; + if (type == Timepoint.TYPE.MINUTE && t.getHour() != time.getHour() && t.getMinute() != time.getMinute()) + continue; // type == SECOND: cannot change anything, return input if (type == Timepoint.TYPE.SECOND) return time; Log.d("Timepoing", "Comparing"); @@ -1136,8 +1163,7 @@ public Timepoint roundToNearest(@NonNull Timepoint time, @Nullable Timepoint.TYP if (newDistance < currentDistance) { currentDistance = newDistance; output = t; - } - else break; + } else break; } return output; } @@ -1157,7 +1183,7 @@ private void setHour(int value, boolean announce) { } } - CharSequence text = String.format(format, value); + CharSequence text = String.format(mLocale, format, value); mHourView.setText(text); mHourSpaceView.setText(text); if (announce) { @@ -1169,17 +1195,17 @@ private void setMinute(int value) { if (value == 60) { value = 0; } - CharSequence text = String.format(Locale.getDefault(), "%02d", value); + CharSequence text = String.format(mLocale, "%02d", value); Utils.tryAccessibilityAnnounce(mTimePicker, text); mMinuteView.setText(text); mMinuteSpaceView.setText(text); } private void setSecond(int value) { - if(value == 60) { + if (value == 60) { value = 0; } - CharSequence text = String.format(Locale.getDefault(), "%02d", value); + CharSequence text = String.format(mLocale, "%02d", value); Utils.tryAccessibilityAnnounce(mTimePicker, text); mSecondView.setText(text); mSecondSpaceView.setText(text); @@ -1187,11 +1213,11 @@ private void setSecond(int value) { // Show either Hours or Minutes. private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate, - boolean announce) { + boolean announce) { mTimePicker.setCurrentItemShowing(index, animateCircle); TextView labelToAnimate; - switch(index) { + switch (index) { case HOUR_INDEX: int hours = mTimePicker.getHours(); if (!mIs24HourMode) { @@ -1236,15 +1262,16 @@ private void setCurrentItemShowing(int index, boolean animateCircle, boolean del /** * For keyboard mode, processes key events. + * * @param keyCode the pressed key. * @return true if the key was successfully processed, false otherwise. */ private boolean processKeyUp(int keyCode) { if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) { - if(isCancelable()) dismiss(); + if (isCancelable()) dismiss(); return true; } else if (keyCode == KeyEvent.KEYCODE_TAB) { - if(mInKbMode) { + if (mInKbMode) { if (isTypedTimeFullyLegal()) { finishKbMode(true); } @@ -1286,7 +1313,7 @@ private boolean processKeyUp(int keyCode) { || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7 || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9 || (!mIs24HourMode && - (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) { + (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) { if (!mInKbMode) { if (mTimePicker == null) { // Something's wrong, because time picker should definitely not be null. @@ -1309,9 +1336,10 @@ private boolean processKeyUp(int keyCode) { /** * Try to start keyboard mode with the specified key, as long as the timepicker is not in the * middle of a touch-event. + * * @param keyCode The key to use as the first press. Keyboard mode will not be started if the - * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting - * key. + * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting + * key. */ private void tryStartingKbMode(int keyCode) { if (mTimePicker.trySettingInputEnabled(false) && @@ -1340,7 +1368,7 @@ private boolean addKeyIfLegal(int keyCode) { } int val = getValFromKeyCode(keyCode); - Utils.tryAccessibilityAnnounce(mTimePicker, String.format(Locale.getDefault(), "%d", val)); + Utils.tryAccessibilityAnnounce(mTimePicker, String.format(mLocale, "%d", val)); // Automatically fill in 0's if AM or PM was legally entered. if (isTypedTimeFullyLegal()) { if (!mIs24HourMode && mTypedTimes.size() <= (textSize - 1)) { @@ -1395,6 +1423,7 @@ private int deleteLastTypedKey() { /** * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time. + * * @param updateDisplays If true, update the displays with the relevant time. */ private void finishKbMode(boolean updateDisplays) { @@ -1417,8 +1446,9 @@ private void finishKbMode(boolean updateDisplays) { * Update the hours, minutes, seconds and AM/PM displays with the typed times. If the typedTimes * is empty, either show an empty display (filled with the placeholder text), or update from the * timepicker's values. + * * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text. - * Otherwise, revert to the timepicker's values. + * Otherwise, revert to the timepicker's values. */ private void updateDisplay(boolean allowEmptyDisplay) { if (!allowEmptyDisplay && mTypedTimes.isEmpty()) { @@ -1429,7 +1459,7 @@ private void updateDisplay(boolean allowEmptyDisplay) { setMinute(minute); setSecond(second); if (!mIs24HourMode) { - updateAmPmDisplay(hour < 12? AM : PM); + updateAmPmDisplay(hour < 12 ? AM : PM); } setCurrentItemShowing(mTimePicker.getCurrentItemShowing(), true, true, true); mOkButton.setEnabled(true); @@ -1440,9 +1470,9 @@ private void updateDisplay(boolean allowEmptyDisplay) { String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d"; String secondFormat = (enteredZeros[1]) ? "%02d" : "%2d"; String hourStr = (values[0] == -1) ? mDoublePlaceholderText : - String.format(hourFormat, values[0]).replace(' ', mPlaceholderText); + String.format(hourFormat, values[0]).replace(' ', mPlaceholderText); String minuteStr = (values[1] == -1) ? mDoublePlaceholderText : - String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); + String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); String secondStr = (values[2] == -1) ? mDoublePlaceholderText : String.format(secondFormat, values[1]).replace(' ', mPlaceholderText); mHourView.setText(hourStr); @@ -1489,9 +1519,10 @@ private static int getValFromKeyCode(int keyCode) { /** * Get the currently-entered time, as integer values of the hours, minutes and seconds typed. + * * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which - * may then be used for the caller to know whether zeros had been explicitly entered as either - * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's. + * may then be used for the caller to know whether zeros had been explicitly entered as either + * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's. * @return A size-3 int array. The first value will be the hours, the second value will be the * minutes, and the third will be either TimePickerDialog.AM or TimePickerDialog.PM. */ @@ -1502,7 +1533,7 @@ private int[] getEnteredTime(Boolean[] enteredZeros) { int keyCode = mTypedTimes.get(mTypedTimes.size() - 1); if (keyCode == getAmOrPmKeyCode(AM)) { amOrPm = AM; - } else if (keyCode == getAmOrPmKeyCode(PM)){ + } else if (keyCode == getAmOrPmKeyCode(PM)) { amOrPm = PM; } startIndex = 2; @@ -1517,7 +1548,7 @@ private int[] getEnteredTime(Boolean[] enteredZeros) { if (i == startIndex) { second = val; } else if (i == startIndex + 1) { - second += 10*val; + second += 10 * val; if (enteredZeros != null && val == 0) { enteredZeros[2] = true; } @@ -1551,7 +1582,7 @@ private int[] getEnteredTime(Boolean[] enteredZeros) { } } - return new int[] {hour, minute, second, amOrPm}; + return new int[]{hour, minute, second, amOrPm}; } /** @@ -1565,8 +1596,8 @@ private int getAmOrPmKeyCode(int amOrPm) { char amChar; char pmChar; for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) { - amChar = mAmText.toLowerCase(Locale.getDefault()).charAt(i); - pmChar = mPmText.toLowerCase(Locale.getDefault()).charAt(i); + amChar = mAmText.toLowerCase(mLocale).charAt(i); + pmChar = mPmText.toLowerCase(mLocale).charAt(i); if (amChar != pmChar) { KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar}); // There should be 4 events: a down and up for both AM and PM. diff --git a/library/src/main/java/net/alhazmy13/hijridatepicker/time/Timepoint.java b/library/src/main/java/net/alhazmy13/hijridatepicker/time/Timepoint.java index 4c40e96..9411733 100644 --- a/library/src/main/java/net/alhazmy13/hijridatepicker/time/Timepoint.java +++ b/library/src/main/java/net/alhazmy13/hijridatepicker/time/Timepoint.java @@ -4,6 +4,7 @@ import android.os.Parcelable; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; /** * Simple utility class that represents a time in the day up to second precision @@ -13,6 +14,7 @@ * * Created by wdullaer on 13/10/15. */ +@SuppressWarnings("WeakerAccess") public class Timepoint implements Parcelable, Comparable { private int hour; private int minute; @@ -71,7 +73,7 @@ public boolean isAM() { } public boolean isPM() { - return hour >= 12 && hour < 24; + return !isAM(); } public void setAM() { @@ -82,23 +84,69 @@ public void setPM() { if(hour < 12) hour = (hour + 12) % 24; } + public void add(TYPE type, int value) { + if (type == TYPE.MINUTE) value *= 60; + if (type == TYPE.HOUR) value *= 3600; + value += toSeconds(); + + switch (type) { + case SECOND: + second = (value % 3600) % 60; + case MINUTE: + minute = (value % 3600) / 60; + case HOUR: + hour = (value / 3600) % 24; + } + } + + public int get(@NonNull TYPE type) { + switch (type) { + case SECOND: + return getSecond(); + case MINUTE: + return getMinute(); + case HOUR: + default: // Makes the compiler happy + return getHour(); + } + } + + public int toSeconds() { + return 3600 * hour + 60 * minute + second; + } + + @Override + public int hashCode() { + return toSeconds(); + } + @Override public boolean equals(Object o) { - try { - Timepoint other = (Timepoint) o; + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - return other.getHour() == hour && - other.getMinute() == minute && - other.getSecond() == second; - } - catch(ClassCastException e) { - return false; + Timepoint timepoint = (Timepoint) o; + + return hashCode() == timepoint.hashCode(); + } + + public boolean equals(@Nullable Timepoint time, @NonNull TYPE resolution) { + if (time == null) return false; + boolean output = true; + switch (resolution) { + case SECOND: + output = output && time.getSecond() == getSecond(); + case MINUTE: + output = output && time.getMinute() == getMinute(); + case HOUR: + output = output && time.getHour() == getHour(); } + return output; } @Override public int compareTo(@NonNull Timepoint t) { - return (this.hour - t.hour)*3600 + (this.minute - t.minute)*60 + (this.second - t.second); + return hashCode() - t.hashCode(); } @Override @@ -113,8 +161,8 @@ public int describeContents() { return 0; } - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { + public static final Creator CREATOR + = new Creator() { public Timepoint createFromParcel(Parcel in) { return new Timepoint(in); } diff --git a/sample/build.gradle b/sample/build.gradle index 79992c0..a2624a4 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,14 +1,14 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 27 + buildToolsVersion "27.0.3" defaultConfig { - minSdkVersion 17 - targetSdkVersion 25 + minSdkVersion 19 + targetSdkVersion 27 versionCode 1 - versionName "1.0.1" + versionName "1.0.2" } buildTypes { release { @@ -24,9 +24,10 @@ android { } dependencies { - compile project(':library') - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:25.2.0' - compile 'com.android.support:design:25.2.0' - compile 'com.android.support:support-v13:25.2.0' + implementation project(':library') + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support:design:27.1.1' + implementation 'com.android.support:support-v13:27.1.1' + implementation group: 'com.github.msarhan', name: 'ummalqura-calendar', version:'1.1.9' } diff --git a/sample/sample.iml b/sample/sample.iml index 715bdea..45ae40b 100644 --- a/sample/sample.iml +++ b/sample/sample.iml @@ -27,20 +27,21 @@ + - + - + @@ -55,6 +56,13 @@ + + + + + + + @@ -77,42 +85,39 @@ - - - - - - - - - - - - - + + + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/GregorianDatePickerFragment.java b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/GregorianDatePickerFragment.java index de02b59..b0816fd 100644 --- a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/GregorianDatePickerFragment.java +++ b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/GregorianDatePickerFragment.java @@ -15,6 +15,7 @@ import net.alhazmy13.hijridatepicker.date.gregorian.GregorianDatePickerDialog; import java.util.Calendar; +import java.util.Locale; /** * A simple {@link Fragment} subclass. @@ -95,6 +96,8 @@ public void onClick(View v) { } // dpd.setSelectableDays(days); } + //Change the language to any of supported language + dpd.setLocale(new Locale("ar")); dpd.show(getFragmentManager(), "Datepickerdialog"); } }); diff --git a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/HijriDatePickerFragment.java b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/HijriDatePickerFragment.java index 1c74552..01ae84e 100644 --- a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/HijriDatePickerFragment.java +++ b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/HijriDatePickerFragment.java @@ -11,9 +11,11 @@ import android.widget.TextView; import com.github.msarhan.ummalqura.calendar.UmmalquraCalendar; + import net.alhazmy13.hijridatepicker.date.hijri.HijriDatePickerDialog; import java.util.Calendar; +import java.util.Locale; /** * A simple {@link Fragment} subclass. @@ -94,6 +96,8 @@ public void onClick(View v) { } // dpd.setSelectableDays(days); } + //Change the language to any of supported language + dpd.setLocale(new Locale("ar")); dpd.show(getFragmentManager(), "Datepickerdialog"); } }); @@ -105,14 +109,13 @@ public void onClick(View v) { public void onResume() { super.onResume(); HijriDatePickerDialog dpd = (HijriDatePickerDialog) getFragmentManager().findFragmentByTag("Datepickerdialog"); - if(dpd != null) dpd.setOnDateSetListener(this); + if (dpd != null) dpd.setOnDateSetListener(this); } - @Override public void onDateSet(HijriDatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { - String date = "You picked the following date: "+dayOfMonth+"/"+(++monthOfYear)+"/"+year; + String date = "You picked the following date: " + dayOfMonth + "/" + (++monthOfYear) + "/" + year; dateTextView.setText(date); } } diff --git a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/TimePickerFragment.java b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/TimePickerFragment.java index 7b854f3..ebc1d49 100644 --- a/sample/src/main/java/net/alhazmy13/hijridatepickerexample/TimePickerFragment.java +++ b/sample/src/main/java/net/alhazmy13/hijridatepickerexample/TimePickerFragment.java @@ -15,6 +15,7 @@ import net.alhazmy13.hijridatepicker.time.TimePickerDialog; import java.util.Calendar; +import java.util.Locale; /** * A simple {@link Fragment} subclass. @@ -85,6 +86,8 @@ public void onCancel(DialogInterface dialogInterface) { Log.d("TimePicker", "Dialog was cancelled"); } }); + //Change the language to any of supported language + tpd.setLocale(new Locale("ar")); tpd.show(getFragmentManager(), "Timepickerdialog"); } }); @@ -96,15 +99,15 @@ public void onCancel(DialogInterface dialogInterface) { public void onResume() { super.onResume(); TimePickerDialog tpd = (TimePickerDialog) getFragmentManager().findFragmentByTag("Timepickerdialog"); - if(tpd != null) tpd.setOnTimeSetListener(this); + if (tpd != null) tpd.setOnTimeSetListener(this); } @Override public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) { - String hourString = hourOfDay < 10 ? "0"+hourOfDay : ""+hourOfDay; - String minuteString = minute < 10 ? "0"+minute : ""+minute; - String secondString = second < 10 ? "0"+second : ""+second; - String time = "You picked the following time: "+hourString+"h"+minuteString+"m"+secondString+"s"; + String hourString = hourOfDay < 10 ? "0" + hourOfDay : "" + hourOfDay; + String minuteString = minute < 10 ? "0" + minute : "" + minute; + String secondString = second < 10 ? "0" + second : "" + second; + String time = "You picked the following time: " + hourString + "h" + minuteString + "m" + secondString + "s"; timeTextView.setText(time); } }