From 44700442f3e09060ca2d6b4bd3d21baebce1e440 Mon Sep 17 00:00:00 2001 From: Tomasz Sapeta <1714764+tsapeta@users.noreply.github.com> Date: Tue, 26 May 2020 01:25:31 +0200 Subject: [PATCH] [android][ios] Update @react-native-community/datetimepicker to 2.4.0 (#8476) --- CHANGELOG.md | 1 + .../RNDatePickerDialogFragment.java | 9 +- .../RNDismissableDatePickerDialog.java | 80 ++++----- .../RNDismissableTimePickerDialog.java | 62 ++++--- .../RNTimePickerDialogFragment.java | 6 +- apps/native-component-list/package.json | 2 +- .../src/screens/DateTimePickerScreen.tsx | 162 ++++++++++-------- ios/Exponent.xcodeproj/project.pbxproj | 1 - .../DateTimePicker/RNDateTimePickerManager.m | 17 ++ packages/expo/bundledNativeModules.json | 2 +- yarn.lock | 8 +- 11 files changed, 190 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8756ab19ed5b1..54f4691d2b2d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDatePickerDialogFragment.java b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDatePickerDialogFragment.java index c6ab8507a0f29..f08081b58885e 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDatePickerDialogFragment.java +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDatePickerDialogFragment.java @@ -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); diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableDatePickerDialog.java b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableDatePickerDialog.java index b1b861def9ab9..4e21a2ead5f23 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableDatePickerDialog.java +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableDatePickerDialog.java @@ -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( @@ -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 @@ -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); diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableTimePickerDialog.java b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableTimePickerDialog.java index 7c5c7ef55a93a..90192bc4125f6 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableTimePickerDialog.java +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNDismissableTimePickerDialog.java @@ -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( @@ -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 @@ -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); diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNTimePickerDialogFragment.java b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNTimePickerDialogFragment.java index e7dd8f9e65ad8..32e9fa22c747f 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNTimePickerDialogFragment.java +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/datetimepicker/RNTimePickerDialogFragment.java @@ -81,7 +81,8 @@ static TimePickerDialog getDialog( onTimeSetListener, hour, minute, - is24hour + is24hour, + display ); } } @@ -90,7 +91,8 @@ static TimePickerDialog getDialog( onTimeSetListener, hour, minute, - is24hour + is24hour, + display ); } diff --git a/apps/native-component-list/package.json b/apps/native-component-list/package.json index d609d56d7e9b2..cbb22b101782f 100644 --- a/apps/native-component-list/package.json +++ b/apps/native-component-list/package.json @@ -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", diff --git a/apps/native-component-list/src/screens/DateTimePickerScreen.tsx b/apps/native-component-list/src/screens/DateTimePickerScreen.tsx index d3a6abaa12044..a706cf423c9a3 100644 --- a/apps/native-component-list/src/screens/DateTimePickerScreen.tsx +++ b/apps/native-component-list/src/screens/DateTimePickerScreen.tsx @@ -1,24 +1,16 @@ -import { - SafeAreaView, - ScrollView, - StyleSheet, - View, - Text, - StatusBar, - Button, - Platform, -} from 'react-native'; +import { ScrollView, StyleSheet, View, Text, Button, Platform, TextInput } from 'react-native'; import DateTimePicker from '@react-native-community/datetimepicker'; import React, { useState } from 'react'; import moment from 'moment'; -// This example is a copy from https://github.com/react-native-community/react-native-datetimepicker/tree/master/example +// This example is a refactored copy from https://github.com/react-native-community/react-native-datetimepicker/tree/master/example // Please try to keep it up to date when updating @react-native-community/datetimepicker package :) const DateTimePickerScreen = () => { const [date, setDate] = useState(new Date(1598051730000)); const [mode, setMode] = useState('date'); const [show, setShow] = useState(false); + const [color, setColor] = useState(); const [display, setDisplay] = useState('default'); const onChange = (event, selectedDate) => { @@ -45,66 +37,86 @@ const DateTimePickerScreen = () => { const showTimepicker = () => { showMode('time'); + setDisplay('default'); + }; + + const showTimepickerSpinner = () => { + showMode('time'); + setDisplay('spinner'); }; return ( - <> - - - - {global.HermesInternal == null ? null : ( - - Engine: Hermes - - )} - - - - Example DateTime Picker - - -