-
Notifications
You must be signed in to change notification settings - Fork 25k
Android datepicker mode configurations added #10932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
By analyzing the blame information on this pull request, we identified @spicyj and @AaaChiuuu to be potential reviewers. |
|
This looks reasonable. Why is it tagged "[URGENT]"? Can you verify that the test failures are unrelated to this change? |
|
@ericvicenti removed the urgent tag from title. The build issues are related to Xcode8, I have changed only the DatePickerDialogModule for android. |
|
Ok, looks great! @facebook-github-bot shipit |
|
@ericvicenti has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
|
We had some test failures internally. Do you know why this would happen? |
|
@ericvicenti I have added custom styles in "react-native/ReactAndroid/src/main/res//shell/values/styles.xml". For reflecting those styles you have to run a clean build on android projects. You need to build the "ReactAndroid" android project. |
|
Hmm. Maybe @mkonicek can help land this, because I have no idea what I'm doing when it comes to best practices around these things. |
|
I tried to merge this pull request into the Facebook internal repo but some checks failed. To unblock yourself please check the following: Does this pull request pass all open source tests on GitHub? If not please fix those. Does the code still apply cleanly on top of GitHub master? If not can please rebase. In all other cases this means some internal test failed, for example a part of a fb app won't work with this pull request. I've added the Import Failed label to this pull request so it is easy for someone at fb to find the pull request and check what failed. If you don't see anyone comment in a few days feel free to comment mentioning one of the core contributors to the project so they get a notification. |
|
@ericvicenti , @mkonicek I have run the "npm test" command inside react-native folder. The test cases are executed successfully. Can someone from android core team have a look at on this. |
|
Try to run |
a3cc751 to
7bcf865
Compare
|
Hi @ericvicenti , @mkonicek , @facebook-github-bot , @leeight Finally, I have found the root cause of the issue("error: cannot find symbol import com.facebook.react.R;"). I have missed the resource dependency in date picker buck file. Now I have added the dependencies to "ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK" file. I run the android unit test cases and it was passed and In an android integration test, date picker modal test cases were passed. FYI.. sh scripts/run-android-local-integration-tests.sh - Result I have re-base the code from master and updated the pull request. |
|
@pandiaraj44 Please stop tagging everyone. It sounds like @mkonicek will look into why the import failed and tell you if anything needs to be changed. |
|
I am re-running internal tests and will land this afternoon if everything passes. |
| * * `date` (`Date` object or timestamp in milliseconds) - date to show by default | ||
| * * `minDate` (`Date` or timestamp in milliseconds) - minimum date that can be selected | ||
| * * `maxDate` (`Date` object or timestamp in milliseconds) - minimum date that can be selected | ||
| * * `calendarMode` (`Boolean` true or false) - To set the date-picker mode to spinner/calendar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use enum type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per the android API documentation, Android date-picker supports only two modes. https://developer.android.com/reference/android/R.styleable.html#DatePicker_datePickerMode
| react_native_target('java/com/facebook/react/bridge:bridge'), | ||
| react_native_target('java/com/facebook/react/common:common'), | ||
| react_native_target('java/com/facebook/react/module/annotations:annotations'), | ||
| react_native_target('res:shell'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually i'm not sure it's right or not add res:shell dependency here, but i guess it's a bad smell...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside ReactAndroid project, The shell resource visibility is in PUBLIC mode. So I have reused that one and added some list of styles to shell resource folder.
I don't think it is necessary to create a resource folder for each of the package in ReactAndroid project.
Maybe if the visibility of the shell is in private mode then I would create separate resource folder.
Ref: https://developer.android.com/guide/topics/ui/themes.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about remove react_native_target('res:shell'), dependency and use context.getResources().getIdentifier instead of R...., for example:
cc @satya164
ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.java
44: final Locale locale = context.getResources().getConfiguration().locale;
ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java
58: final int heightResId = context.getResources()
61: PixelUtil.toDIPFromPixel(context.getResources().getDimensionPixelSize(heightResId)) :
ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java
55: DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java
601: Resources resources = v.getContext().getResources();
ReactAndroid/src/main/java/com/facebook/react/views/imagehelper/ResourceDrawableIdHelper.java
54: int id = context.getResources().getIdentifier(
64: return resId > 0 ? context.getResources().getDrawable(resId) : null;
ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java
167: return new GenericDraweeHierarchyBuilder(context.getResources())
ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java
80: int resId = context.getResources().getIdentifier(
97: Resources resources = getThemedContext().getResources();
ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbar.java
301: return new GenericDraweeHierarchyBuilder(getResources())
308: return getResources().getIdentifier(
317: return getResources().getDrawable(getDrawableResourceByName(name));
ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java
41: int attrID = context.getResources().getIdentifier(attr, "attr", "android");
49: return context.getResources()
52: return context.getResources().getDrawable(sResolveOutValue.resourceId);
72: color = context.getResources().getColor(sResolveOutValue.resourceId);
|
Hi @ericvicenti , FYI... All git hub checks have passed. |
c3e250d to
aa514dc
Compare
|
Hi @ericvicenti , Again I have re-base my code from upstream and tests have passed. |
|
cc @leeight |
|
@pandiaraj44 Can you address @leeight 's nits regarding whitespace please? |
| @@ -0,0 +1 @@ | |||
| 5 4f:}&� dl�8mH No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@satya164 While running test cases that file get created. I removed that file and updated the pull request.
|
@satya164 Thank you very much for your information. |
|
|
||
| final DatePickerDialog dialog = | ||
| new DismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day); | ||
| DatePickerMode mode = DatePickerMode.DEFAULT; //To set mode to default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please remove comment that repeats what the code does without adding information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment has been removed.
| onDateSetListener, year, month, day); | ||
| break; | ||
| case DEFAULT: | ||
| //To Show a default native date picker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment has been removed.
| break; | ||
| case SPINNER: | ||
| dialog.getDatePicker().setCalendarViewShown(false); | ||
| break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in this switch statement should be moved up to the branches where the dialogs are created.
| break; | ||
| } | ||
| } else { | ||
| dialog = new DismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible to write the code above without repeating this line twice:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mode == DatePickerMode.CALENDAR) {
// Create picker with calendar
} else (if mode == DatePickerMode.SPINNER) {
// Create picker with spinner
}
}
// Default case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setCalendarViewShown has been deprecated in latest android API version. So build version "if condition" is mandatory.
We can remove the dialog creation line but it requires extra two if condition
DatePickerDialog dialog = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
switch (mode) {
case CALENDAR:
dialog = new DismissableDatePickerDialog(activityContext,
activityContext.getResources().getIdentifier("CalendarDatePickerDialog", "style", activityContext.getPackageName()),
onDateSetListener, year, month, day);
break;
case SPINNER:
dialog = new DismissableDatePickerDialog(activityContext,
activityContext.getResources().getIdentifier("SpinnerDatePickerDialog", "style", activityContext.getPackageName()),
onDateSetListener, year, month, day);
break;
}
}
if (dialog == null) {
dialog = new DismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
switch (mode) {
case CALENDAR:
dialog.getDatePicker().setCalendarViewShown(true);
dialog.getDatePicker().setSpinnersShown(false);
break;
case SPINNER:
dialog.getDatePicker().setCalendarViewShown(false);
break;
}
}
For supporting future cases, I have used a switch statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks!
| mValue = value; | ||
| } | ||
|
|
||
| public static DatePickerMode fromString(String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would valueOf work instead?
http://stackoverflow.com/questions/604424/lookup-enum-by-string-value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ValueOf has been implemented. For that, we need to match the user values with enum constants.
|
|
||
| <style name="CalendarDatePickerStyle" parent="android:Widget.Material.Light.DatePicker" tools:targetApi="lollipop"> | ||
| <item name="android:datePickerMode">calendar</item> | ||
| </style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed for these styles to be defined in resources? Is it possible to set the android:datePickerMode programmatically instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latest Android API doesn't provide the default methods to change the mode.
Ref: https://developer.android.com/reference/android/widget/DatePicker.html#attr_android:calendarViewShown ,
https://developer.android.com/reference/android/widget/DatePicker.html#attr_android:datePickerMode
|
Thanks! @facebook-github-bot shipit |
| break; | ||
| } | ||
| } else { | ||
| dialog = new DismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks!
Summary: Currently, The **DatePickerAndroid** component opens the native date picker with default mode. We can't able to change the mode via configurations. To support android **[date-picker mode](https://developer.android.com/reference/android/widget/DatePicker.html)**, existing component needs to be changed. **For Android >= 5.0**, The DatePickerDialog doesn't provide the default method to change the mode of a date picker. So I have added custom theme which will support two kinds of **mode('spinner','calendar')** ref:https://developer.android.com/reference/android/R.attr.html#datePickerStyle. **For Android < 5.0,** The DatePickerDialog provides the default method to change the mode of a date picker. ref:https://developer.android.com/reference/android/widget/DatePicker.html#setCalendarViewShown(boolean). With the help of **Build.VERSION.SDK_INT** I have done the above functionality with limited lines of code changes and also I have added the example to UIExplorer. Closes facebook/react-native#10932 Differential Revision: D4176089 Pulled By: ericvicenti fbshipit-source-id: 7dfa9101214501ac2124bda7ee273a538f04e7cf
Summary: Currently, The **DatePickerAndroid** component opens the native date picker with default mode. We can't able to change the mode via configurations. To support android **[date-picker mode](https://developer.android.com/reference/android/widget/DatePicker.html)**, existing component needs to be changed. **For Android >= 5.0**, The DatePickerDialog doesn't provide the default method to change the mode of a date picker. So I have added custom theme which will support two kinds of **mode('spinner','calendar')** ref:https://developer.android.com/reference/android/R.attr.html#datePickerStyle. **For Android < 5.0,** The DatePickerDialog provides the default method to change the mode of a date picker. ref:https://developer.android.com/reference/android/widget/DatePicker.html#setCalendarViewShown(boolean). With the help of **Build.VERSION.SDK_INT** I have done the above functionality with limited lines of code changes and also I have added the example to UIExplorer. Closes facebook#10932 Differential Revision: D4176089 Pulled By: ericvicenti fbshipit-source-id: 7dfa9101214501ac2124bda7ee273a538f04e7cf
Summary: In the spirit of #10932, I added the `mode` option to the `TimePicker` Android API. There is only one mode available for **Android < 5**, the `spinner` one. If we are on **Android >= 5** we can choose between `spinner` or `clock`. If we specify `default` it will use the default of the current Android version. On **Android < 5**, whatever we choose it will be this:  On **Android >= 5**, with the `spinner` mode:  And with the `clock` mode, the default:  Closes #12384 Differential Revision: D6006689 Pulled By: hramos fbshipit-source-id: fcd37c867c4061b9982b1687f2c10211e54df7cf



Motivation
Currently, The DatePickerAndroid component opens the native date picker with default mode. We can't able to change the mode via configurations. To support android date-picker mode, existing component needs to be changed.
Solution
For Android >= 5.0, The DatePickerDialog doesn't provide the default method to change the mode of a date picker. So I have added custom theme which will support two kinds of mode('spinner','calendar') ref:https://developer.android.com/reference/android/R.attr.html#datePickerStyle.
For Android < 5.0, The DatePickerDialog provides the default method to change the mode of a date picker. ref:https://developer.android.com/reference/android/widget/DatePicker.html#setCalendarViewShown(boolean).
With the help of Build.VERSION.SDK_INT I have done the above functionality with limited lines of code changes and also I have added the example to UIExplorer.
Test Plan
When opening a date picker on Android, We need to pass the option value(mode: 'calendar/spinner/default').
Example1:
DatePickerAndroid.open({ date: Date.now(), mode: 'calendar'}) // It will open datepicker with calendar mode
Android < 5.0

Android >= 5.0

Example2:
DatePickerAndroid.open({ date: Date.now(), mode: 'spinner'}) // It will open datepicker with spinner mode
Android < 5.0

Android >= 5.0

Example3:
DatePickerAndroid.open({ date: Date.now()})
(or)
DatePickerAndroid.open({ date: Date.now(), mode: 'default'})
// It will open datepicker with default native mode based on android versions.
Android < 5.0

Android >= 5.0

So If the user doesn't give mode option then default mode will be shown.
For real-time testing, you can run UIExplorer android project. I have added example code.
