From c4eb6231f33cfc9e40a4f1bcd0eb2a7aed5cf324 Mon Sep 17 00:00:00 2001 From: Henning Hall Date: Sun, 14 Apr 2019 19:24:09 +0200 Subject: [PATCH] Max/min-date performance improvements --- DatePickerAndroid.js | 4 +- .../henninghall/date_picker/DateBoundary.java | 17 ++++++ .../date_picker/DatePickerManager.java | 18 +++--- .../henninghall/date_picker/PickerView.java | 60 +++++++------------ .../date_picker/WheelChangeListenerImpl.java | 50 ++++++++++++++++ .../date_picker/wheels/DayWheel.java | 10 ++-- .../date_picker/wheels/YearWheel.java | 8 +-- 7 files changed, 109 insertions(+), 58 deletions(-) create mode 100644 android/src/main/java/com/henninghall/date_picker/DateBoundary.java create mode 100644 android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java diff --git a/DatePickerAndroid.js b/DatePickerAndroid.js index cc7a0ea..e524d35 100644 --- a/DatePickerAndroid.js +++ b/DatePickerAndroid.js @@ -11,7 +11,7 @@ class DatePickerAndroid extends React.Component { minuteInterval: 1, }; - render = () => { + render(){ return ( this.props.minimumDate && this._toIsoWithTimeZoneOffset(this.props.maximumDate); + _maximumDate = () => this.props.maximumDate && this._toIsoWithTimeZoneOffset(this.props.maximumDate); _minimumDate = () => this.props.minimumDate && this._toIsoWithTimeZoneOffset(this.props.minimumDate); diff --git a/android/src/main/java/com/henninghall/date_picker/DateBoundary.java b/android/src/main/java/com/henninghall/date_picker/DateBoundary.java new file mode 100644 index 0000000..4a01f78 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/DateBoundary.java @@ -0,0 +1,17 @@ +package com.henninghall.date_picker; + +import java.util.Calendar; + +public class DateBoundary { + private Calendar date; + + public DateBoundary(PickerView pickerView, String date) { + if(date == null) return; + Calendar cal = Utils.isoToCalendar(date, pickerView.timeZone); + this.date = Utils.getTruncatedCalendarOrNull(cal); + } + + protected Calendar get() { + return this.date; + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java b/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java index 20d322b..c081e48 100644 --- a/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java +++ b/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java @@ -57,12 +57,12 @@ public class DatePickerManager extends SimpleViewManager { @ReactProp(name = "minimumDate") public void setMinimumDate(PickerView view, @Nullable String date) { - this.minimumDate = date; + view.setMinimumDate(date); } @ReactProp(name = "maximumDate") public void setMaximumDate(PickerView view, @Nullable String date) { - this.maximumDate = date; + view.setMaximumDate(date); } @ReactProp(name = "fadeToColor") @@ -83,21 +83,17 @@ public class DatePickerManager extends SimpleViewManager { @ReactProp(name = "utc") public void setUtc(PickerView view, @Nullable boolean utc) throws Exception { - this.utc = utc; + TimeZone timeZone = utc ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault(); + view.setTimeZone(timeZone); } @Override protected void onAfterUpdateTransaction(PickerView view) { super.onAfterUpdateTransaction(view); - - TimeZone timeZone = utc ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault(); - view.setTimeZone(timeZone); - if(minimumDate != null) view.setMinimumDate(Utils.isoToCalendar(minimumDate, timeZone)); - if(maximumDate != null) view.setMaximumDate(Utils.isoToCalendar(maximumDate, timeZone)); - - // Refresh which options are available. Should happen before updating the date + // updateDisplayValuesIfNeeded() refreshes + // which options are available. Should happen before updating the selected date. view.updateDisplayValuesIfNeeded(); - view.setDate(Utils.isoToCalendar(date, timeZone)); + view.setDate(date); } public Map getExportedCustomBubblingEventTypeConstants() { diff --git a/android/src/main/java/com/henninghall/date_picker/PickerView.java b/android/src/main/java/com/henninghall/date_picker/PickerView.java index fd019b0..9f46ad0 100644 --- a/android/src/main/java/com/henninghall/date_picker/PickerView.java +++ b/android/src/main/java/com/henninghall/date_picker/PickerView.java @@ -1,6 +1,7 @@ package com.henninghall.date_picker; import android.os.Build; +import android.util.Log; import android.view.View; import android.widget.RelativeLayout; @@ -37,7 +38,7 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView; public class PickerView extends RelativeLayout { - private SimpleDateFormat dateFormat; + public SimpleDateFormat dateFormat; private HourWheel hourWheel; private DayWheel dayWheel; public MinutesWheel minutesWheel; @@ -49,13 +50,12 @@ public class PickerView extends RelativeLayout { public DateWheel dateWheel; public MonthWheel monthWheel; public YearWheel yearWheel; - public Calendar maxDate; - public Calendar minDate; private WheelOrderUpdater wheelOrderUpdater; - public boolean isInitialized = false; public boolean requireDisplayValueUpdate = true; - public TimeZone timeZone; - + public TimeZone timeZone = TimeZone.getDefault(); + private DateBoundary minDate; + private DateBoundary maxDate; + private WheelChangeListener onWheelChangeListener = new WheelChangeListenerImpl(this); public PickerView() { super(DatePickerManager.context); @@ -71,37 +71,15 @@ public class PickerView extends RelativeLayout { yearWheel = new YearWheel( this, R.id.year); monthWheel = new MonthWheel( this, R.id.month); dateWheel = new DateWheel( this, R.id.date); - dayWheel = new DayWheel( this, R.id.day); minutesWheel = new MinutesWheel( this, R.id.minutes); ampmWheel = new AmPmWheel(this, R.id.ampm); hourWheel = new HourWheel(this, R.id.hour); - dateFormat = new SimpleDateFormat(getDateFormatTemplate(), Locale.US); + changeAmPmWhenPassingMidnightOrNoon(); } - WheelChangeListener onWheelChangeListener = new WheelChangeListener(){ - @Override - public void onChange(Wheel wheel) { - WritableMap event = Arguments.createMap(); - try { - dateFormat.setTimeZone(timeZone); - Calendar date = Calendar.getInstance(timeZone); - date.setTime(dateFormat.parse(getDateString())); - - if (minDate != null && date.before(minDate)) applyOnVisibleWheels(new AnimateToDate(minDate)); - else if (maxDate != null && date.after(maxDate)) applyOnVisibleWheels(new AnimateToDate(maxDate)); - else { - event.putString("date", Utils.dateToIso(date)); - DatePickerManager.context.getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "dateChange", event); - } - } catch (ParseException e) { - e.printStackTrace(); - } - } - }; - private final Runnable measureAndLayout = new Runnable() { @Override @@ -127,17 +105,18 @@ public class PickerView extends RelativeLayout { }); } - public void setMinimumDate(Calendar cal) { - minDate = Utils.getTruncatedCalendarOrNull(cal); + public void setMinimumDate(String date) { + minDate = new DateBoundary(this, date); requireDisplayValueUpdate = true; } - public void setMaximumDate(Calendar cal) { - maxDate = Utils.getTruncatedCalendarOrNull(cal); + public void setMaximumDate(String date) { + maxDate = new DateBoundary(this, date); requireDisplayValueUpdate = true; } - public void setDate(Calendar cal) { + public void setDate(String isoDate) { + Calendar cal = Utils.isoToCalendar(isoDate, timeZone); applyOnAllWheels(new SetDate(cal)); } @@ -179,7 +158,7 @@ public class PickerView extends RelativeLayout { + ampmWheel.getFormatTemplate(); } - private String getDateString() { + public String getDateString() { String dateString= (mode == Mode.date) ? (yearWheel.getValue() + " " + monthWheel.getValue() + " " @@ -235,9 +214,16 @@ public class PickerView extends RelativeLayout { public void setTimeZone(TimeZone timeZone) { this.timeZone = timeZone; + requireDisplayValueUpdate = true; + } + + public Calendar getMinimumDate(){ + if (minDate == null) return null; + return minDate.get(); } - public TimeZone getTimeZone() { - return timeZone; + public Calendar getMaximumDate(){ + if (maxDate == null) return null; + return maxDate.get(); } } diff --git a/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java b/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java new file mode 100644 index 0000000..4dc3734 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java @@ -0,0 +1,50 @@ +package com.henninghall.date_picker; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.RCTEventEmitter; +import com.henninghall.date_picker.wheelFunctions.AnimateToDate; +import com.henninghall.date_picker.wheels.Wheel; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +public class WheelChangeListenerImpl implements WheelChangeListener { + + + private final PickerView pickerView; + + public WheelChangeListenerImpl(PickerView pickerView) { + this.pickerView = pickerView; + } + + @Override + public void onChange(Wheel picker) { + WritableMap event = Arguments.createMap(); + TimeZone timeZone = pickerView.timeZone; + SimpleDateFormat dateFormat = pickerView.dateFormat; + Calendar minDate = pickerView.getMinimumDate(); + Calendar maxDate = pickerView.getMaximumDate(); + try { + dateFormat.setTimeZone(timeZone); + Calendar date = Calendar.getInstance(timeZone); + date.setTime(dateFormat.parse(this.pickerView.getDateString())); + + if (minDate != null && date.before(minDate)) pickerView.applyOnVisibleWheels( + new AnimateToDate(minDate) + ); + else if (maxDate != null && date.after(maxDate)) pickerView.applyOnVisibleWheels( + new AnimateToDate(maxDate) + ); + else { + event.putString("date", Utils.dateToIso(date)); + DatePickerManager.context.getJSModule(RCTEventEmitter.class).receiveEvent(pickerView.getId(), "dateChange", event); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java index bc3881c..21a713c 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java @@ -35,8 +35,9 @@ public class DayWheel extends Wheel { private Calendar getStartCal(){ Calendar cal; - if (pickerView.minDate != null) { - cal = (Calendar) pickerView.minDate.clone(); + Calendar min = pickerView.getMinimumDate(); + if (min != null) { + cal = (Calendar) min.clone(); resetToMidnight(cal); } else { cal = (Calendar) pickerView.getInitialDate().clone(); @@ -47,8 +48,9 @@ public class DayWheel extends Wheel { private Calendar getEndCal(){ Calendar cal; - if (pickerView.maxDate != null) { - cal = (Calendar) pickerView.maxDate.clone(); + Calendar max = pickerView.getMaximumDate(); + if (max != null) { + cal = (Calendar) max.clone(); resetToMidnight(cal); } else { cal = (Calendar) pickerView.getInitialDate().clone(); diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java index db4e674..dca3fa9 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java @@ -34,17 +34,17 @@ public class YearWheel extends Wheel } private int getEndYear() { - if (this.pickerView.maxDate == null) { + if (this.pickerView.getMaximumDate() == null) { return this.defaultEndYear; } - return this.pickerView.maxDate.get(Calendar.YEAR); + return this.pickerView.getMaximumDate().get(Calendar.YEAR); } private int getStartYear() { - if (this.pickerView.minDate == null) { + if (this.pickerView.getMinimumDate() == null) { return this.defaultStartYear; } - return this.pickerView.minDate.get(Calendar.YEAR); + return this.pickerView.getMinimumDate().get(Calendar.YEAR); } @Override