Skip to content

Commit

Permalink
[android][ios] Update @react-native-community/datetimepicker to 2.4.0 (
Browse files Browse the repository at this point in the history
  • Loading branch information
tsapeta committed May 25, 2020
1 parent c0b27a9 commit 4470044
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 160 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@ Package-specific changes not released in any SDK will be added here just before
- Updated `react-native-screens` from `2.2.0` to `2.8.0`. ([#8434](https://github.com/expo/expo/pull/8424) by [@sjchmiela](https://github.com/sjchmiela))
- Updated `react-native-shared-element` from `0.5.6` to `0.7.0`. ([#8427](https://github.com/expo/expo/pull/8427) by [@IjzerenHein](https://github.com/IjzerenHein))
- Updated `react-native-reanimated` from `1.7.0` to `1.9.0`. ([#8424](https://github.com/expo/expo/pull/8424) by [@sjchmiela](https://github.com/sjchmiela))
- Updated `@react-native-community/datetimepicker` from `2.2.2` to `2.4.0`. ([#8476](https://github.com/expo/expo/pull/8476) by [@tsapeta](https://github.com/tsapeta))

### 🛠 Breaking changes

Expand Down
Expand Up @@ -82,18 +82,21 @@ DatePickerDialog getDialog(
onDateSetListener,
year,
month,
day);
day,
display
);
default:
return new RNDismissableDatePickerDialog(
activityContext,
onDateSetListener,
year,
month,
day
day,
display
);
}
} else {
DatePickerDialog dialog = new RNDismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day);
DatePickerDialog dialog = new RNDismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day, display);
switch (display) {
case CALENDAR:
dialog.getDatePicker().setCalendarViewShown(true);
Expand Down
Expand Up @@ -37,9 +37,10 @@ public RNDismissableDatePickerDialog(
@Nullable DatePickerDialog.OnDateSetListener callback,
int year,
int monthOfYear,
int dayOfMonth) {
int dayOfMonth,
RNDatePickerDisplay display) {
super(context, callback, year, monthOfYear, dayOfMonth);
fixSpinner(context, year, monthOfYear, dayOfMonth);
fixSpinner(context, year, monthOfYear, dayOfMonth, display);
}

public RNDismissableDatePickerDialog(
Expand All @@ -48,9 +49,10 @@ public RNDismissableDatePickerDialog(
@Nullable DatePickerDialog.OnDateSetListener callback,
int year,
int monthOfYear,
int dayOfMonth) {
int dayOfMonth,
RNDatePickerDisplay display) {
super(context, theme, callback, year, monthOfYear, dayOfMonth);
fixSpinner(context, year, monthOfYear, dayOfMonth);
fixSpinner(context, year, monthOfYear, dayOfMonth, display);
}

@Override
Expand All @@ -62,57 +64,43 @@ protected void onStop() {
}
}

private void fixSpinner(Context context, int year, int month, int dayOfMonth) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
private void fixSpinner(Context context, int year, int month, int dayOfMonth, RNDatePickerDisplay display) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N && display == RNDatePickerDisplay.SPINNER) {
try {
// Get the theme's android:datePickerMode
final int MODE_SPINNER = 2;
Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
Field datePickerStyleableField = styleableClass.getField("DatePicker");
int[] datePickerStyleable = (int[]) datePickerStyleableField.get(null);

final TypedArray a =
context.obtainStyledAttributes(
null, datePickerStyleable, android.R.attr.datePickerStyle, 0);
Field datePickerModeStyleableField = styleableClass.getField("DatePicker_datePickerMode");
int datePickerModeStyleable = datePickerModeStyleableField.getInt(null);
final int mode = a.getInt(datePickerModeStyleable, MODE_SPINNER);
final TypedArray a = context.obtainStyledAttributes(null, datePickerStyleable, android.R.attr.datePickerStyle, 0);
a.recycle();

if (mode == MODE_SPINNER) {
DatePicker datePicker =
(DatePicker)
findField(DatePickerDialog.class, DatePicker.class, "mDatePicker").get(this);
Class<?> delegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate");
Field delegateField = findField(DatePicker.class, delegateClass, "mDelegate");
Object delegate = delegateField.get(datePicker);
Class<?> spinnerDelegateClass;
spinnerDelegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate");
DatePicker datePicker = (DatePicker)findField(DatePickerDialog.class, DatePicker.class, "mDatePicker").get(this);
Class<?> delegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate");
Field delegateField = findField(DatePicker.class, delegateClass, "mDelegate");
Object delegate = delegateField.get(datePicker);
Class<?> spinnerDelegateClass;
spinnerDelegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate");

// In 7.0 Nougat for some reason the datePickerMode is ignored and the delegate is
// DatePickerClockDelegate
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(datePicker, null); // throw out the DatePickerClockDelegate!
datePicker.removeAllViews(); // remove the DatePickerClockDelegate views
Method createSpinnerUIDelegate =
DatePicker.class.getDeclaredMethod(
"createSpinnerUIDelegate",
Context.class,
AttributeSet.class,
int.class,
int.class);
createSpinnerUIDelegate.setAccessible(true);
// In 7.0 Nougat for some reason the datePickerMode is ignored and the delegate is
// DatePickerClockDelegate
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(datePicker, null); // throw out the DatePickerClockDelegate!
datePicker.removeAllViews(); // remove the DatePickerClockDelegate views
Method createSpinnerUIDelegate =
DatePicker.class.getDeclaredMethod(
"createSpinnerUIDelegate",
Context.class,
AttributeSet.class,
int.class,
int.class);
createSpinnerUIDelegate.setAccessible(true);

// Instantiate a DatePickerSpinnerDelegate throughout createSpinnerUIDelegate method
delegate =
createSpinnerUIDelegate.invoke(
datePicker, context, null, android.R.attr.datePickerStyle, 0);
delegateField.set(
datePicker, delegate); // set the DatePicker.mDelegate to the spinner delegate
datePicker.setCalendarViewShown(false);
// Initialize the date for the DatePicker delegate again
datePicker.init(year, month, dayOfMonth, this);
}
// Instantiate a DatePickerSpinnerDelegate throughout createSpinnerUIDelegate method
delegate = createSpinnerUIDelegate.invoke(datePicker, context, null, android.R.attr.datePickerStyle, 0);
delegateField.set(datePicker, delegate); // set the DatePicker.mDelegate to the spinner delegate
datePicker.setCalendarViewShown(false);
// Initialize the date for the DatePicker delegate again
datePicker.init(year, month, dayOfMonth, this);
}
} catch (Exception e) {
throw new RuntimeException(e);
Expand Down
Expand Up @@ -38,9 +38,10 @@ public RNDismissableTimePickerDialog(
@Nullable TimePickerDialog.OnTimeSetListener callback,
int hourOfDay,
int minute,
boolean is24HourView) {
boolean is24HourView,
RNTimePickerDisplay display) {
super(context, callback, hourOfDay, minute, is24HourView);
fixSpinner(context, hourOfDay, minute, is24HourView);
fixSpinner(context, hourOfDay, minute, is24HourView, display);
}

public RNDismissableTimePickerDialog(
Expand All @@ -49,9 +50,10 @@ public RNDismissableTimePickerDialog(
@Nullable TimePickerDialog.OnTimeSetListener callback,
int hourOfDay,
int minute,
boolean is24HourView) {
boolean is24HourView,
RNTimePickerDisplay display) {
super(context, theme, callback, hourOfDay, minute, is24HourView);
fixSpinner(context, hourOfDay, minute, is24HourView);
fixSpinner(context, hourOfDay, minute, is24HourView, display);
}

@Override
Expand All @@ -61,41 +63,35 @@ protected void onStop() {
}
}

private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView, RNTimePickerDisplay display) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N && display == RNTimePickerDisplay.SPINNER) {
try {
// Get the theme's android:timePickerMode
final int MODE_SPINNER = 1;
Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
Field timePickerStyleableField = styleableClass.getField("TimePicker");
int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null);
final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0);
Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode");
int timePickerModeStyleable = timePickerModeStyleableField.getInt(null);
final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER);
a.recycle();
if (mode == MODE_SPINNER) {
TimePicker timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this);
Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate");
Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate");
Object delegate = delegateField.get(timePicker);
Class<?> spinnerDelegateClass;
spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate");
// In 7.0 Nougat for some reason the timePickerMode is ignored and the delegate is TimePickerClockDelegate
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate!
timePicker.removeAllViews(); // remove the TimePickerClockDelegate views
Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class);
spinnerDelegateConstructor.setAccessible(true);
// Instantiate a TimePickerSpinnerDelegate
delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0);
delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate
// Set up the TimePicker again, with the TimePickerSpinnerDelegate
timePicker.setIs24HourView(is24HourView);
timePicker.setCurrentHour(hourOfDay);
timePicker.setCurrentMinute(minute);
timePicker.setOnTimeChangedListener(this);
}

TimePicker timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this);
Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate");
Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate");
Object delegate = delegateField.get(timePicker);
Class<?> spinnerDelegateClass;
spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate");
// In 7.0 Nougat for some reason the timePickerMode is ignored and the delegate is TimePickerClockDelegate
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate!
timePicker.removeAllViews(); // remove the TimePickerClockDelegate views
Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class);
spinnerDelegateConstructor.setAccessible(true);
// Instantiate a TimePickerSpinnerDelegate
delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0);
delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate
// Set up the TimePicker again, with the TimePickerSpinnerDelegate
timePicker.setIs24HourView(is24HourView);
timePicker.setCurrentHour(hourOfDay);
timePicker.setCurrentMinute(minute);
timePicker.setOnTimeChangedListener(this);
}
} catch (Exception e) {
throw new RuntimeException(e);
Expand Down
Expand Up @@ -81,7 +81,8 @@ static TimePickerDialog getDialog(
onTimeSetListener,
hour,
minute,
is24hour
is24hour,
display
);
}
}
Expand All @@ -90,7 +91,8 @@ static TimePickerDialog getDialog(
onTimeSetListener,
hour,
minute,
is24hour
is24hour,
display
);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/native-component-list/package.json
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@expo/react-native-action-sheet": "^2.0.1",
"@react-native-community/datetimepicker": "2.2.2",
"@react-native-community/datetimepicker": "2.4.0",
"@react-native-community/masked-view": "0.1.6",
"@react-native-community/netinfo": "5.9.0",
"@react-native-community/segmented-control": "1.6.1",
Expand Down

0 comments on commit 4470044

Please sign in to comment.