From 9edc7bcc8e2bd40541371041cfd59b95a9e6ead9 Mon Sep 17 00:00:00 2001 From: Henning Hall Date: Sun, 16 Feb 2020 21:40:48 +0100 Subject: [PATCH] Improved architecture Separating concerns Remove duplicated code --- .../henninghall/date_picker/DateBoundary.java | 6 +- .../date_picker/DatePickerManager.java | 115 +++----- .../date_picker/EmptyWheelUpdater.java | 42 --- .../henninghall/date_picker/PickerView.java | 260 ++++-------------- .../com/henninghall/date_picker/Settings.java | 12 - .../com/henninghall/date_picker/State.java | 206 ++++++++++++++ .../com/henninghall/date_picker/Style.java | 61 ---- .../com/henninghall/date_picker/Utils.java | 7 + .../date_picker/WheelChangeListenerImpl.java | 56 ---- .../henninghall/date_picker/WheelOrder.java | 109 -------- .../date_picker/WheelPosition.java | 5 - .../date_picker/{ => models}/Mode.java | 2 +- .../date_picker/{ => models}/WheelType.java | 2 +- .../date_picker/props/DateProp.java | 13 + .../date_picker/props/FadeToColorProp.java | 13 + .../date_picker/props/HeightProp.java | 13 + .../date_picker/props/LocaleProp.java | 28 ++ .../date_picker/props/MaximumDateProp.java | 13 + .../date_picker/props/MinimumDateProp.java | 13 + .../date_picker/props/MinuteIntervalProp.java | 17 ++ .../date_picker/props/ModeProp.java | 13 + .../henninghall/date_picker/props/Prop.java | 28 ++ .../date_picker/props/TextColorProp.java | 13 + .../date_picker/props/UtcProp.java | 12 + .../date_picker/ui/EmptyWheels.java | 45 +++ .../date_picker/ui/FadingOverlay.java | 42 +++ .../henninghall/date_picker/ui/UIManager.java | 87 ++++++ .../{ => ui}/WheelChangeListener.java | 2 +- .../ui/WheelChangeListenerImpl.java | 60 ++++ .../date_picker/ui/WheelScroller.java | 19 ++ .../henninghall/date_picker/ui/Wheels.java | 186 +++++++++++++ .../wheelFunctions/AddOnChangeListener.java | 27 ++ .../date_picker/wheels/AmPmWheel.java | 16 +- .../date_picker/wheels/DateWheel.java | 14 +- .../date_picker/wheels/DayWheel.java | 31 ++- .../date_picker/wheels/HourWheel.java | 19 +- .../date_picker/wheels/MinutesWheel.java | 20 +- .../date_picker/wheels/MonthWheel.java | 7 +- .../henninghall/date_picker/wheels/Wheel.java | 32 +-- .../date_picker/wheels/YearWheel.java | 21 +- 40 files changed, 1046 insertions(+), 641 deletions(-) delete mode 100644 android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java delete mode 100644 android/src/main/java/com/henninghall/date_picker/Settings.java create mode 100644 android/src/main/java/com/henninghall/date_picker/State.java delete mode 100644 android/src/main/java/com/henninghall/date_picker/Style.java delete mode 100644 android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java delete mode 100644 android/src/main/java/com/henninghall/date_picker/WheelOrder.java delete mode 100644 android/src/main/java/com/henninghall/date_picker/WheelPosition.java rename android/src/main/java/com/henninghall/date_picker/{ => models}/Mode.java (51%) rename android/src/main/java/com/henninghall/date_picker/{ => models}/WheelType.java (63%) create mode 100644 android/src/main/java/com/henninghall/date_picker/props/DateProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/HeightProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/ModeProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/Prop.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/props/UtcProp.java create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/UIManager.java rename android/src/main/java/com/henninghall/date_picker/{ => ui}/WheelChangeListener.java (76%) create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java create mode 100644 android/src/main/java/com/henninghall/date_picker/ui/Wheels.java create mode 100644 android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java diff --git a/android/src/main/java/com/henninghall/date_picker/DateBoundary.java b/android/src/main/java/com/henninghall/date_picker/DateBoundary.java index e709898..18dcd05 100644 --- a/android/src/main/java/com/henninghall/date_picker/DateBoundary.java +++ b/android/src/main/java/com/henninghall/date_picker/DateBoundary.java @@ -1,13 +1,15 @@ package com.henninghall.date_picker; + import java.util.Calendar; +import java.util.TimeZone; public class DateBoundary { private Calendar date; - DateBoundary(PickerView pickerView, String date) { + DateBoundary(TimeZone timezone, String date) { if(date == null) return; - Calendar cal = Utils.isoToCalendar(date, pickerView.timeZone); + Calendar cal = Utils.isoToCalendar(date, timezone); this.date = Utils.getTruncatedCalendarOrNull(cal); } 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 f15bd7f..800583e 100644 --- a/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java +++ b/android/src/main/java/com/henninghall/date_picker/DatePickerManager.java @@ -1,25 +1,32 @@ package com.henninghall.date_picker; + +import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; +import com.henninghall.date_picker.props.DateProp; +import com.henninghall.date_picker.props.FadeToColorProp; +import com.henninghall.date_picker.props.LocaleProp; +import com.henninghall.date_picker.props.MaximumDateProp; +import com.henninghall.date_picker.props.MinimumDateProp; +import com.henninghall.date_picker.props.MinuteIntervalProp; +import com.henninghall.date_picker.props.ModeProp; +import com.henninghall.date_picker.props.TextColorProp; +import com.henninghall.date_picker.props.UtcProp; import net.time4j.android.ApplicationStarter; -import org.apache.commons.lang3.LocaleUtils; +import java.lang.reflect.Method; import java.util.Map; -import java.util.TimeZone; public class DatePickerManager extends SimpleViewManager { - public static final String REACT_CLASS = "DatePickerManager"; + private static final String REACT_CLASS = "DatePickerManager"; private static final int SCROLL = 1; - public static ThemedReactContext context; - private String date; @Override public String getName() { @@ -33,69 +40,36 @@ public class DatePickerManager extends SimpleViewManager { return new PickerView(); } - @ReactProp(name = "mode") - public void setMode(PickerView view, String mode) { - Mode m; - try { - m = Mode.valueOf(mode); - } catch (Exception e) { - throw new IllegalArgumentException("Invalid mode. Valid modes: 'datetime', 'date', 'time'"); - } - view.setMode(m); - } - - @ReactProp(name = "date") - public void setDate(PickerView view, String date) { - this.date = date; - } - - @ReactProp(name = "locale") - public void setLocale(PickerView view, String locale) { - view.setLocale(LocaleUtils.toLocale(locale.replace('-','_'))); - } - - @ReactProp(name = "minimumDate") - public void setMinimumDate(PickerView view, String date) { - view.setMinimumDate(date); - } - - @ReactProp(name = "maximumDate") - public void setMaximumDate(PickerView view, String date) { - view.setMaximumDate(date); - } - - @ReactProp(name = "fadeToColor") - public void setFadeToColor(PickerView view, String color) { - view.style.setFadeToColor(color); - } - - @ReactProp(name = "textColor") - public void setTextColor(PickerView view, String color) { - view.style.setTextColor(color); - } - - @ReactProp(name = "minuteInterval") - public void setMinuteInterval(PickerView view, int interval) throws Exception { - if (interval < 0 || interval > 59) throw new Exception("Minute interval out of bounds"); - view.setMinuteInterval(interval); - } + @ReactPropGroup(names = { DateProp.name, ModeProp.name, LocaleProp.name, MaximumDateProp.name, + MinimumDateProp.name, FadeToColorProp.name, TextColorProp.name, UtcProp.name, MinuteIntervalProp.name}) + public void setProps(PickerView view, int index, Dynamic value) { + String[] propNames = getMethodAnnotation("setProps").names(); + String propName = propNames[index]; + view.updateProp(propName, value); - @ReactProp(name = "utc") - public void setUtc(PickerView view, boolean utc) throws Exception { - TimeZone timeZone = utc ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault(); - view.setTimeZone(timeZone); } - @ReactPropGroup(names = {"height", "width"}, customType = "Style") + @ReactPropGroup(names = {}, customType = "Style") public void setStyle(PickerView view, int index, Integer style) { - if(index == 0) view.style.setHeight(style); + if(index == 0) { + view.updateProp("height", null); + } } @Override public Map getCommandsMap() { - return MapBuilder.of( - "scroll", SCROLL - ); + return MapBuilder.of("scroll", SCROLL); + } + + @Override + protected void onAfterUpdateTransaction(PickerView pickerView) { + super.onAfterUpdateTransaction(pickerView); + try{ + pickerView.update(); + } + catch (Exception e){ + e.printStackTrace(); + } } public void receiveCommand(final PickerView view, int command, final ReadableArray args) { @@ -106,15 +80,6 @@ public class DatePickerManager extends SimpleViewManager { } } - @Override - protected void onAfterUpdateTransaction(PickerView view) { - super.onAfterUpdateTransaction(view); - // updateDisplayValuesIfNeeded() refreshes - // which options are available. Should happen before updating the selected date. - view.updateDisplayValuesIfNeeded(); - view.setDate(date); - } - public Map getExportedCustomBubblingEventTypeConstants() { return MapBuilder.builder() .put("dateChange", MapBuilder.of("phasedRegistrationNames", @@ -123,6 +88,16 @@ public class DatePickerManager extends SimpleViewManager { ).build(); } + private ReactPropGroup getMethodAnnotation(String methodName) { + Method[] methods = this.getClass().getMethods(); + Method method = null; + for (Method m : methods) { + if (m.getName().equals(methodName)) + method = m; + } + return method.getAnnotation(ReactPropGroup.class); + } + } diff --git a/android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java b/android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java deleted file mode 100644 index 58d61e9..0000000 --- a/android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.henninghall.date_picker; - -import java.util.HashMap; -import cn.carbswang.android.numberpickerview.library.NumberPickerView; - -public class EmptyWheelUpdater { - - private final PickerView pickerView; - private final HashMap views; - - EmptyWheelUpdater(PickerView pickerView) { - this.pickerView = pickerView; - this.views = getViews(); - } - - private HashMap getViews() { - HashMap views = new HashMap<>(); - for (int id: Utils.emptyWheelIds) { - NumberPickerView view = (NumberPickerView) pickerView.findViewById(id); - views.put(id, view); - } - return views; - } - - void update() { - hideAll(); - int numberOfVisibleWheels = pickerView.getVisibleWheels().size(); - int emptyViewsToAdd = numberOfVisibleWheels + 1; - - for (int i = 0; i < emptyViewsToAdd; i++) { - int index = i * 2; - pickerView.wheelsWrapper.addView(views.get(Utils.emptyWheelIds[i]), index); - } - } - - private void hideAll() { - for (NumberPickerView view: views.values()) { - pickerView.wheelsWrapper.removeView(view); - } - } - -} 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 7321e3d..cb34194 100644 --- a/android/src/main/java/com/henninghall/date_picker/PickerView.java +++ b/android/src/main/java/com/henninghall/date_picker/PickerView.java @@ -1,199 +1,92 @@ package com.henninghall.date_picker; -import android.os.Build; import android.view.View; -import android.widget.LinearLayout; import android.widget.RelativeLayout; -import com.henninghall.date_picker.wheelFunctions.Refresh; -import com.henninghall.date_picker.wheelFunctions.SetDate; -import com.henninghall.date_picker.wheelFunctions.UpdateVisibility; -import com.henninghall.date_picker.wheelFunctions.WheelFunction; -import com.henninghall.date_picker.wheels.AmPmWheel; -import com.henninghall.date_picker.wheels.DateWheel; -import com.henninghall.date_picker.wheels.DayWheel; -import com.henninghall.date_picker.wheels.HourWheel; -import com.henninghall.date_picker.wheels.MinutesWheel; -import com.henninghall.date_picker.wheels.MonthWheel; -import com.henninghall.date_picker.wheels.Wheel; -import com.henninghall.date_picker.wheels.YearWheel; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; - -import cn.carbswang.android.numberpickerview.library.NumberPickerView; +import com.facebook.react.bridge.Dynamic; +import com.henninghall.date_picker.props.DateProp; +import com.henninghall.date_picker.props.FadeToColorProp; +import com.henninghall.date_picker.props.HeightProp; +import com.henninghall.date_picker.props.LocaleProp; +import com.henninghall.date_picker.props.ModeProp; +import com.henninghall.date_picker.props.TextColorProp; +import com.henninghall.date_picker.ui.UIManager; +import java.util.ArrayList; public class PickerView extends RelativeLayout { - public LinearLayout wheelsWrapper; - public HourWheel hourWheel; - public DayWheel dayWheel; - public MinutesWheel minutesWheel; - public AmPmWheel ampmWheel; - public int minuteInterval = 1; - public Locale locale; - public Mode mode; - public Style style; - public DateWheel dateWheel; - public MonthWheel monthWheel; - public YearWheel yearWheel; - private WheelOrder wheelOrder; - EmptyWheelUpdater emptyWheelUpdater; - public boolean requireDisplayValueUpdate = true; - public TimeZone timeZone = TimeZone.getDefault(); - private DateBoundary minDate; - private DateBoundary maxDate; - private WheelChangeListener onWheelChangeListener = new WheelChangeListenerImpl(this); + private final View rootView = inflate(getContext(), R.layout.datepicker_view, this); + private final UIManager uiManager; + private State state; + private ArrayList updatedProps = new ArrayList<>(); public PickerView() { super(DatePickerManager.context); - - View rootView = inflate(getContext(), R.layout.datepicker_view, this); - style = new Style(this); - - locale = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Locale.forLanguageTag("en") : Locale.getDefault(); - - wheelsWrapper = (LinearLayout) rootView.findViewById(R.id.wheelsWrapper); - wheelsWrapper.setWillNotDraw(false); - - 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); - - emptyWheelUpdater = new EmptyWheelUpdater(this); - wheelOrder = new WheelOrder(this); - - changeAmPmWhenPassingMidnightOrNoon(); + state = new State(); + uiManager = new UIManager(state, this); } - private final Runnable measureAndLayout = new Runnable() { - @Override - public void run() { - measure( - MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY)); - layout(getLeft(), getTop(), getRight(), getBottom()); - } - }; - - private void changeAmPmWhenPassingMidnightOrNoon(){ - hourWheel.picker.setOnValueChangeListenerInScrolling(new NumberPickerView.OnValueChangeListenerInScrolling() { - @Override - public void onValueChangeInScrolling(NumberPickerView picker, int oldVal, int newVal) { - if(Settings.usesAmPm()){ - String oldValue = hourWheel.getValueAtIndex(oldVal); - String newValue = hourWheel.getValueAtIndex(newVal); - boolean passingNoonOrMidnight = (oldValue.equals("12") && newValue.equals("11")) || oldValue.equals("11") && newValue.equals("12"); - if (passingNoonOrMidnight) ampmWheel.picker.smoothScrollToValue((ampmWheel.picker.getValue() + 1) % 2,false); - } - } - }); - } + public void update() { + if(updatedProps.contains(FadeToColorProp.name)) { + uiManager.updateFadeToColor(); + } - public void setMinimumDate(String date) { - minDate = new DateBoundary(this, date); - requireDisplayValueUpdate = true; - } - - public void setMaximumDate(String date) { - maxDate = new DateBoundary(this, date); - requireDisplayValueUpdate = true; - } + if(updatedProps.contains(TextColorProp.name)) { + uiManager.updateTextColor(); + } - public void setDate(String isoDate) { - Calendar cal = Utils.isoToCalendar(isoDate, timeZone); - applyOnAllWheels(new SetDate(cal)); - } + if(updatedProps.contains(ModeProp.name)) { + uiManager.updateWheelVisibility(); + } - public void setLocale(Locale locale) { - this.locale = locale; - wheelOrder.update(locale); - requireDisplayValueUpdate = true; - } + if(updatedProps.contains(HeightProp.name)) { + uiManager.updateHeight(); + } - public void setMinuteInterval(int interval) { - this.minuteInterval = interval; - requireDisplayValueUpdate = true; - } + if(updatedProps.contains(ModeProp.name) || updatedProps.contains(LocaleProp.name)) { + uiManager.updateWheelOrder(); + } - // Rounding cal to closest minute interval - public Calendar getInitialDate() { - Calendar cal = Calendar.getInstance(); - if(minuteInterval <= 1) return cal; - int exactMinute = Integer.valueOf(minutesWheel.format.format(cal.getTime())); - int diffSinceLastInterval = exactMinute % minuteInterval; - int diffAhead = minuteInterval - diffSinceLastInterval; - int diffBehind= -diffSinceLastInterval; - boolean closerToPrevious = minuteInterval / 2 > diffSinceLastInterval; - int diffToExactValue = closerToPrevious ? diffBehind : diffAhead; - cal.add(Calendar.MINUTE, diffToExactValue); - return (Calendar) cal.clone(); - } + ArrayList nonRefreshingProps = new ArrayList(){{ + add(DateProp.name); + add(FadeToColorProp.name); + add(TextColorProp.name); + }}; + updatedProps.removeAll(nonRefreshingProps); - private String getDateFormatPattern(){ - if(mode == Mode.date){ - return wheelOrder.getVisibleWheel(0).getFormatPattern() + " " - + wheelOrder.getVisibleWheel(1).getFormatPattern() + " " - + wheelOrder.getVisibleWheel(2).getFormatPattern(); + if(updatedProps.size() != 0) { + uiManager.updateDisplayValues(); } - return dayWheel.getFormatPattern(); - } - - private String getFormatPattern() { - return this.getDateFormatPattern() + " " - + hourWheel.getFormatPattern() + " " - + minutesWheel.getFormatPattern() - + ampmWheel.getFormatPattern(); - } - public String getDateString() { - String dateString = (mode == Mode.date) - ? wheelOrder.getVisibleWheel(0).getValue() + " " - + wheelOrder.getVisibleWheel(1).getValue() + " " - + wheelOrder.getVisibleWheel(2).getValue() - : dayWheel.getValue(); - return dateString - + " " + hourWheel.getValue() - + " " + minutesWheel.getValue() - + ampmWheel.getValue(); - } + uiManager.setWheelsToDate(); - public void setMode(Mode mode) { - this.mode = mode; - applyOnAllWheels(new UpdateVisibility()); - wheelOrder.update(locale); - requireDisplayValueUpdate = true; + updatedProps = new ArrayList<>(); } - public Collection getVisibleWheels() { - Collection visibleWheels = new ArrayList<>(); - for (Wheel wheel: getAllWheels()) if (wheel.visible()) visibleWheels.add(wheel); - return visibleWheels; + public void updateProp(String propName, Dynamic value) { + state.setProp(propName, value); + updatedProps.add(propName); } - public List getAllWheels(){ - return new ArrayList<>(Arrays.asList(yearWheel, monthWheel, dateWheel, dayWheel, hourWheel, minutesWheel, ampmWheel)); + public void scroll(int wheelIndex, int scrollTimes) { + uiManager.scroll(wheelIndex, scrollTimes); } - public void applyOnAllWheels(WheelFunction function) { - for (Wheel wheel: getAllWheels()) function.apply(wheel); + public View getRootView(){ + return rootView; } - public void applyOnVisibleWheels(WheelFunction function) { - for (Wheel wheel: getVisibleWheels()) function.apply(wheel); - } + private final Runnable measureAndLayout = new Runnable() { + @Override + public void run() { + measure( + MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY)); + layout(getLeft(), getTop(), getRight(), getBottom()); + } + }; @Override public void requestLayout() { @@ -201,45 +94,6 @@ public class PickerView extends RelativeLayout { post(measureAndLayout); } - public WheelChangeListener getListener() { - return onWheelChangeListener; - } - - public void updateDisplayValuesIfNeeded() { - if(requireDisplayValueUpdate) { - applyOnAllWheels(new Refresh()); - requireDisplayValueUpdate = false; - } - } - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - requireDisplayValueUpdate = true; - } - - public Calendar getMinimumDate(){ - if (minDate == null) return null; - return minDate.get(); - } - public Calendar getMaximumDate(){ - if (maxDate == null) return null; - return maxDate.get(); - } - - protected SimpleDateFormat getDateFormat() { - return new SimpleDateFormat(getFormatPattern(), locale); - } - - public void scroll(int wheelIndex, int scrollTimes) { - NumberPickerView picker = wheelOrder.getVisibleWheel(wheelIndex).picker; - int currentIndex = picker.getValue(); - int maxValue = picker.getMaxValue(); - boolean isWrapping = picker.getWrapSelectorWheel(); - int nextValue = currentIndex + scrollTimes; - if(nextValue <= maxValue || isWrapping) { - picker.smoothScrollToValue(nextValue % (maxValue + 1)); - } - - } } diff --git a/android/src/main/java/com/henninghall/date_picker/Settings.java b/android/src/main/java/com/henninghall/date_picker/Settings.java deleted file mode 100644 index 52c53ad..0000000 --- a/android/src/main/java/com/henninghall/date_picker/Settings.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.henninghall.date_picker; - - -import android.text.format.DateFormat; - -public class Settings { - - public static boolean usesAmPm (){ - return !DateFormat.is24HourFormat(DatePickerManager.context); - } - -} diff --git a/android/src/main/java/com/henninghall/date_picker/State.java b/android/src/main/java/com/henninghall/date_picker/State.java new file mode 100644 index 0000000..ebc2bdf --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/State.java @@ -0,0 +1,206 @@ +package com.henninghall.date_picker; + +import android.util.Log; + +import com.facebook.react.bridge.Dynamic; +import com.henninghall.date_picker.models.Mode; +import com.henninghall.date_picker.models.WheelType; +import com.henninghall.date_picker.props.DateProp; +import com.henninghall.date_picker.props.FadeToColorProp; +import com.henninghall.date_picker.props.HeightProp; +import com.henninghall.date_picker.props.LocaleProp; +import com.henninghall.date_picker.props.MaximumDateProp; +import com.henninghall.date_picker.props.MinimumDateProp; +import com.henninghall.date_picker.props.MinuteIntervalProp; +import com.henninghall.date_picker.props.ModeProp; +import com.henninghall.date_picker.props.Prop; +import com.henninghall.date_picker.props.TextColorProp; +import com.henninghall.date_picker.props.UtcProp; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Locale; +import java.util.TimeZone; + +public class State { + + private final Prop dateProp = new DateProp(); + private final Prop modeProp = new ModeProp(); + private final Prop localeProp = new LocaleProp(); + private final Prop fadeToColorProp = new FadeToColorProp(); + private final Prop textColorProp = new TextColorProp(); + private final Prop minuteIntervalProp = new MinuteIntervalProp(); + private final Prop minimumDateProp = new MinimumDateProp(); + private final Prop maximumDateProp = new MaximumDateProp(); + private final Prop utcProp = new UtcProp(); + private final Prop heightProp = new HeightProp(); + + private final HashMap props = new HashMap() {{ + put(DateProp.name, dateProp); + put(ModeProp.name, modeProp); + put(LocaleProp.name, localeProp); + put(FadeToColorProp.name, fadeToColorProp); + put(TextColorProp.name, textColorProp); + put(MinuteIntervalProp.name, minuteIntervalProp); + put(MinimumDateProp.name, minimumDateProp); + put(MaximumDateProp.name, maximumDateProp); + put(UtcProp.name, utcProp); + }}; + + private Prop getProp(String name){ + return (Prop) props.get(name); + } + + void setProp(String propName, Dynamic value){ + getProp(propName).setValue(value); + } + + public Mode getMode() { + return (Mode) modeProp.getValue(); + } + + public String getFadeToColor() { + return (String) fadeToColorProp.getValue(); + } + + public String getTextColor() { + return (String) textColorProp.getValue(); + } + + public int getMinuteInterval() { + return (int) minuteIntervalProp.getValue(); + } + + public Locale getLocale() { + return (Locale) localeProp.getValue(); + } + + public Calendar getMinimumDate(){ + DateBoundary db = new DateBoundary(getTimeZone(), (String) minimumDateProp.getValue()); + return db.get(); + } + + public Calendar getMaximumDate(){ + DateBoundary db = new DateBoundary(getTimeZone(), (String) maximumDateProp.getValue()); + return db.get(); + } + + public TimeZone getTimeZone(){ + boolean utc = (boolean) utcProp.getValue(); + return utc ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault(); + } + + public Calendar getDate() { + String date = (String) dateProp.getValue(); + return Utils.isoToCalendar(date, getTimeZone()); + } + + public Integer getHeight() { + return (Integer) heightProp.getValue(); + } + + public int getShownCount() { + int DP_PER_SHOW_SHOW_COUNT = 35; + int showCount = getHeight() / DP_PER_SHOW_SHOW_COUNT; + int oddShowCount = showCount % 2 == 0 ? showCount + 1 : showCount; + return oddShowCount; + } + + public ArrayList getOrderedWheels() { + String dateTimePattern = LocaleUtils.getDateTimePattern(getLocale()); + ArrayList unorderedTypes = new ArrayList(Arrays.asList(WheelType.values())); + ArrayList orderedWheels = new ArrayList<>(); + + // Always put day wheel first + unorderedTypes.remove(WheelType.DAY); + orderedWheels.add(WheelType.DAY); + + for (char ch : dateTimePattern.toCharArray()){ + try { + WheelType wheelType = Utils.patternCharToWheelType(ch); + if (unorderedTypes.contains(wheelType)) { + unorderedTypes.remove(wheelType); + orderedWheels.add(wheelType); + } + } catch (Exception e) { + // ignore unknown pattern chars that not correspond to any wheel type + } + } + // If AM/PM wheel remains it means that the locale does not have AM/PM by default and it + // should be put last. + if(unorderedTypes.contains(WheelType.AM_PM)){ + unorderedTypes.remove(WheelType.AM_PM); + orderedWheels.add(WheelType.AM_PM); + } + + if(!unorderedTypes.isEmpty()) { + Log.e( + "RNDatePicker", + unorderedTypes.size() + " wheel types cannot be ordered. Wheel type 0: " + unorderedTypes.get(0)); + } + + return orderedWheels; + } + + public ArrayList getVisibleWheels() { + ArrayList visibleWheels = new ArrayList<>(); + Mode mode = getMode(); + switch (mode){ + case datetime: { + visibleWheels.add(WheelType.DAY); + visibleWheels.add(WheelType.HOUR); + visibleWheels.add(WheelType.MINUTE); + break; + } + case time: { + visibleWheels.add(WheelType.HOUR); + visibleWheels.add(WheelType.MINUTE); + break; + } + case date: { + visibleWheels.add(WheelType.YEAR); + visibleWheels.add(WheelType.MONTH); + visibleWheels.add(WheelType.DATE); + break; + } + } + if((mode == Mode.time || mode == Mode.datetime) && Utils.usesAmPm()){ + visibleWheels.add(WheelType.AM_PM); + } + return visibleWheels; + } + + public ArrayList getOrderedVisibleWheels() { + ArrayList orderedWheels = getOrderedWheels(); + ArrayList visibleWheels = getVisibleWheels(); + ArrayList visibleOrderedWheels = new ArrayList<>(); + for (WheelType wheel : orderedWheels){ + if(visibleWheels.contains(wheel)) visibleOrderedWheels.add(wheel); + } + return visibleOrderedWheels; + } + + // Rounding cal to closest minute interval + public Calendar getInitialDate() { + Calendar cal = Calendar.getInstance(); + int minuteInterval = getMinuteInterval(); + if(minuteInterval <= 1) return cal; + SimpleDateFormat minuteFormat = new SimpleDateFormat("mm", getLocale()); + int exactMinute = Integer.valueOf(minuteFormat.format(cal.getTime())); + int diffSinceLastInterval = exactMinute % minuteInterval; + int diffAhead = minuteInterval - diffSinceLastInterval; + int diffBehind= -diffSinceLastInterval; + boolean closerToPrevious = minuteInterval / 2 > diffSinceLastInterval; + int diffToExactValue = closerToPrevious ? diffBehind : diffAhead; + cal.add(Calendar.MINUTE, diffToExactValue); + return (Calendar) cal.clone(); + } + + + public WheelType getVisibleWheel(int index) { + return getOrderedVisibleWheels().get(index); + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/Style.java b/android/src/main/java/com/henninghall/date_picker/Style.java deleted file mode 100644 index 89a9000..0000000 --- a/android/src/main/java/com/henninghall/date_picker/Style.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.henninghall.date_picker; - -import android.graphics.Color; -import android.graphics.drawable.GradientDrawable; -import android.widget.ImageView; -import com.henninghall.date_picker.wheelFunctions.SetShowCount; -import com.henninghall.date_picker.wheelFunctions.TextColor; - -import cn.carbswang.android.numberpickerview.library.NumberPickerView; - - -class Style { - private static int DP_PER_SHOW_SHOW_COUNT = 35; - - private final GradientDrawable gradientBottom; - private final GradientDrawable gradientTop; - private final PickerView pickerView; - - public Style(PickerView pickerView) { - this.pickerView = pickerView; - ImageView overlayTop = (ImageView) pickerView.findViewById(R.id.overlay_top); - ImageView overlayBottom = (ImageView) pickerView.findViewById(R.id.overlay_bottom); - this.gradientTop = (GradientDrawable) overlayTop.getDrawable(); - this.gradientBottom = (GradientDrawable) overlayBottom.getDrawable(); - } - - public void setFadeToColor(String color) { - int alpha = validColor(color) ? 255 : 0; - gradientTop.setAlpha(alpha); - gradientBottom.setAlpha(alpha); - if(validColor(color)) { - int startColor = Color.parseColor("#FF"+ color.substring(1)); - int endColor = Color.parseColor("#00" + color.substring(1)); - gradientTop.setColors(new int[] {startColor, endColor}); - gradientBottom.setColors(new int[] {startColor, endColor}); - } - } - - public void setTextColor(String color) { - this.pickerView.applyOnAllWheels(new TextColor(color)); - } - - public void setHeight(int height) { - int showCount = height / DP_PER_SHOW_SHOW_COUNT; - int oddShowCount = showCount % 2 == 0 ? showCount + 1 : showCount; - pickerView.applyOnAllWheels(new SetShowCount(oddShowCount)); - setShownCountOnEmptyWheels(oddShowCount); - } - - private void setShownCountOnEmptyWheels(int shownCount) { - for (int id : Utils.emptyWheelIds) { - NumberPickerView view = (NumberPickerView) pickerView.findViewById(id); - if(view != null) view.setShownCount(shownCount); - } - } - - private boolean validColor(String color){ - return color != null && color.length() == 7; - } - -} diff --git a/android/src/main/java/com/henninghall/date_picker/Utils.java b/android/src/main/java/com/henninghall/date_picker/Utils.java index fa79d80..1dc2195 100644 --- a/android/src/main/java/com/henninghall/date_picker/Utils.java +++ b/android/src/main/java/com/henninghall/date_picker/Utils.java @@ -1,8 +1,11 @@ package com.henninghall.date_picker; +import android.text.format.DateFormat; import android.text.format.DateUtils; +import com.henninghall.date_picker.models.WheelType; + import net.time4j.PrettyTime; import java.text.ParseException; @@ -15,6 +18,10 @@ import java.util.TimeZone; public class Utils { + public static boolean usesAmPm(){ + return !DateFormat.is24HourFormat(DatePickerManager.context); + } + public static int[] emptyWheelIds = { R.id.emptyStart, R.id.empty1, diff --git a/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java b/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java deleted file mode 100644 index abc921a..0000000 --- a/android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -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.DateFormat; -import java.text.FieldPosition; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -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.getDateFormat(); - Calendar minDate = pickerView.getMinimumDate(); - Calendar maxDate = pickerView.getMaximumDate(); - try { - dateFormat.setTimeZone(timeZone); - Calendar date = Calendar.getInstance(timeZone); - String toParse = this.pickerView.getDateString(); - Date newDate = dateFormat.parse(toParse); - date.setTime(newDate); - - - 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/WheelOrder.java b/android/src/main/java/com/henninghall/date_picker/WheelOrder.java deleted file mode 100644 index fdf24a2..0000000 --- a/android/src/main/java/com/henninghall/date_picker/WheelOrder.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.henninghall.date_picker; - -import com.henninghall.date_picker.wheels.Wheel; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; - -public class WheelOrder -{ - - private final HashMap wheelPerWheelType; - private PickerView pickerView; - private ArrayList orderedWheels; - - WheelOrder(final PickerView view) { - this.pickerView = view; - this.wheelPerWheelType = new HashMap() {{ - put(WheelType.DAY, pickerView.dayWheel); - put(WheelType.YEAR, pickerView.yearWheel); - put(WheelType.MONTH, pickerView.monthWheel); - put(WheelType.DATE, pickerView.dateWheel); - put(WheelType.HOUR, pickerView.hourWheel); - put(WheelType.MINUTE, pickerView.minutesWheel); - put(WheelType.AM_PM, pickerView.ampmWheel); - }}; - } - - private void updateAllWheels(final Locale locale) { - try { - this.orderedWheels = getOrderedWheels(locale); - pickerView.wheelsWrapper.removeAllViews(); - for (int i = 0; i < wheelPerWheelType.size(); i++) { - Wheel w = getWheels(i); - if(w.visible()) { - pickerView.wheelsWrapper.addView(w.picker); - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - - void update(final Locale locale) { - updateAllWheels(locale); - pickerView.emptyWheelUpdater.update(); - } - - private Wheel getWheels(int index){ - return wheelPerWheelType.get(orderedWheels.get(index)); - } - - Wheel getVisibleWheel(int index){ - return getVisibleWheels().get(index); - } - - private ArrayList getVisibleWheels() { - ArrayList visibleOrderedWheels = new ArrayList<>(); - for (WheelType wheelType : orderedWheels){ - Wheel wheel = wheelPerWheelType.get(wheelType); - if(wheel.visible()) { - visibleOrderedWheels.add(wheel); - } - } - return visibleOrderedWheels; - } - - private ArrayList getOrderedWheels(Locale locale) throws Exception { - String dateTimePattern = LocaleUtils.getDateTimePattern(locale); - ArrayList unorderedTypes = new ArrayList(Arrays.asList(WheelType.values())); - ArrayList orderedWheels = new ArrayList<>(); - - // Always put day wheel first - unorderedTypes.remove(WheelType.DAY); - orderedWheels.add(WheelType.DAY); - - for (char ch : dateTimePattern.toCharArray()){ - try { - WheelType wheelType = Utils.patternCharToWheelType(ch); - if (unorderedTypes.contains(wheelType)) { - unorderedTypes.remove(wheelType); - orderedWheels.add(wheelType); - } - } catch (Exception e) { - // ignore unknown pattern chars that not correspond to any wheel type - } - } - // If AM/PM wheel remains it means that the locale does not have AM/PM by default and it - // should be put last. - if(unorderedTypes.contains(WheelType.AM_PM)){ - unorderedTypes.remove(WheelType.AM_PM); - orderedWheels.add(WheelType.AM_PM); - } - - if(!unorderedTypes.isEmpty()) { - throw new Exception(unorderedTypes.size() + " wheel types cannot be ordered. Wheel type 0: " + unorderedTypes.get(0)); - } - - return orderedWheels; - } - - - - -} - diff --git a/android/src/main/java/com/henninghall/date_picker/WheelPosition.java b/android/src/main/java/com/henninghall/date_picker/WheelPosition.java deleted file mode 100644 index 5a9eda7..0000000 --- a/android/src/main/java/com/henninghall/date_picker/WheelPosition.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.henninghall.date_picker; - -public enum WheelPosition { - LEFT, RIGHT, MIDDLE -} diff --git a/android/src/main/java/com/henninghall/date_picker/Mode.java b/android/src/main/java/com/henninghall/date_picker/models/Mode.java similarity index 51% rename from android/src/main/java/com/henninghall/date_picker/Mode.java rename to android/src/main/java/com/henninghall/date_picker/models/Mode.java index 43b03f1..041b6fa 100644 --- a/android/src/main/java/com/henninghall/date_picker/Mode.java +++ b/android/src/main/java/com/henninghall/date_picker/models/Mode.java @@ -1,4 +1,4 @@ -package com.henninghall.date_picker; +package com.henninghall.date_picker.models; public enum Mode { date, time, datetime diff --git a/android/src/main/java/com/henninghall/date_picker/WheelType.java b/android/src/main/java/com/henninghall/date_picker/models/WheelType.java similarity index 63% rename from android/src/main/java/com/henninghall/date_picker/WheelType.java rename to android/src/main/java/com/henninghall/date_picker/models/WheelType.java index 933c5c1..d9dcb48 100644 --- a/android/src/main/java/com/henninghall/date_picker/WheelType.java +++ b/android/src/main/java/com/henninghall/date_picker/models/WheelType.java @@ -1,4 +1,4 @@ -package com.henninghall.date_picker; +package com.henninghall.date_picker.models; public enum WheelType { DAY, DATE, MONTH, YEAR, HOUR, MINUTE, AM_PM diff --git a/android/src/main/java/com/henninghall/date_picker/props/DateProp.java b/android/src/main/java/com/henninghall/date_picker/props/DateProp.java new file mode 100644 index 0000000..df238d8 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/DateProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class DateProp extends Prop { + public static final String name = "date"; + + @Override + public String toValue(Dynamic value){ + return value.asString(); + } + +} \ No newline at end of file diff --git a/android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java b/android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java new file mode 100644 index 0000000..de0787a --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class FadeToColorProp extends Prop { + public static final String name = "fadeToColor"; + + @Override + public String toValue(Dynamic value){ + return value.asString(); + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/HeightProp.java b/android/src/main/java/com/henninghall/date_picker/props/HeightProp.java new file mode 100644 index 0000000..20ef9b6 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/HeightProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; +import com.henninghall.date_picker.models.Mode; + +public class HeightProp extends Prop { + public static final String name = "height"; + + @Override + public Integer toValue(Dynamic value){ + return value.asInt(); + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java b/android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java new file mode 100644 index 0000000..3cae162 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java @@ -0,0 +1,28 @@ +package com.henninghall.date_picker.props; + +import android.os.Build; + +import com.facebook.react.bridge.Dynamic; + +import org.apache.commons.lang3.LocaleUtils; + +import java.util.Locale; + +public class LocaleProp extends Prop { + public static final String name = "locale"; + + public LocaleProp(){ + super( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + ? Locale.forLanguageTag("en") + : Locale.getDefault() + ); + } + + @Override + public Locale toValue(Dynamic value){ + return LocaleUtils.toLocale(value.asString().replace('-','_')); + } + +} + diff --git a/android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java b/android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java new file mode 100644 index 0000000..80272fb --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class MaximumDateProp extends Prop { + public static final String name = "maximumDate"; + + @Override + public String toValue(Dynamic value){ + return value.asString(); + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java b/android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java new file mode 100644 index 0000000..1fd5205 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class MinimumDateProp extends Prop { + public static final String name = "minimumDate"; + + @Override + public String toValue(Dynamic value){ + return value.asString(); + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java b/android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java new file mode 100644 index 0000000..e9f1898 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java @@ -0,0 +1,17 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; +import com.henninghall.date_picker.models.Mode; + +public class MinuteIntervalProp extends Prop { + public static final String name = "minuteInterval"; + + public MinuteIntervalProp(){ + super(1); + } + + public Integer toValue(Dynamic value){ + return value.asInt(); + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/ModeProp.java b/android/src/main/java/com/henninghall/date_picker/props/ModeProp.java new file mode 100644 index 0000000..e24d075 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/ModeProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; +import com.henninghall.date_picker.models.Mode; + +public class ModeProp extends Prop { + public static final String name = "mode"; + + @Override + public Mode toValue(Dynamic value){ + return Mode.valueOf(value.asString()); + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/Prop.java b/android/src/main/java/com/henninghall/date_picker/props/Prop.java new file mode 100644 index 0000000..d9ccf99 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/Prop.java @@ -0,0 +1,28 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public abstract class Prop { + private T value; + + public Prop() { } + + public Prop(T defaultValue) { + value = defaultValue; + } + + abstract T toValue(Dynamic value); + + public void setValue(Dynamic value){ + this.value = toValue(value); + } + + public void setValue(T value){ + this.value = value; + } + + public T getValue(){ + return value; + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java b/android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java new file mode 100644 index 0000000..af0b7cb --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java @@ -0,0 +1,13 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class TextColorProp extends Prop { + public static final String name = "textColor"; + + @Override + public String toValue(Dynamic value){ + return value.asString(); + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/props/UtcProp.java b/android/src/main/java/com/henninghall/date_picker/props/UtcProp.java new file mode 100644 index 0000000..60e14c2 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/props/UtcProp.java @@ -0,0 +1,12 @@ +package com.henninghall.date_picker.props; + +import com.facebook.react.bridge.Dynamic; + +public class UtcProp extends Prop { + public static final String name = "utc"; + + @Override + Boolean toValue(Dynamic value) { + return value.asBoolean(); + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java b/android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java new file mode 100644 index 0000000..69867ee --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java @@ -0,0 +1,45 @@ +package com.henninghall.date_picker.ui; + +import android.view.View; + +import com.henninghall.date_picker.PickerView; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; + +import java.util.HashMap; +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + +public class EmptyWheels { + + private final HashMap views; + private final Wheels wheels; + private View rootView; + private State state; + + EmptyWheels(View rootView, Wheels wheels, State state) { + this.wheels = wheels; + this.rootView = rootView; + this.state = state; + this.views = getViews(); + } + + private HashMap getViews() { + HashMap views = new HashMap<>(); + for (int id: Utils.emptyWheelIds) { + NumberPickerView view = (NumberPickerView) rootView.findViewById(id); + views.put(id, view); + } + return views; + } + + void add() { + int numberOfVisibleWheels = state.getVisibleWheels().size(); + int emptyViewsToAdd = numberOfVisibleWheels + 1; + for (int i = 0; i < emptyViewsToAdd; i++) { + int index = i * 2; + wheels.addWheel(views.get(Utils.emptyWheelIds[i]), index); + } + } + + +} diff --git a/android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java b/android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java new file mode 100644 index 0000000..b604767 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java @@ -0,0 +1,42 @@ +package com.henninghall.date_picker.ui; + +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.view.View; +import android.widget.ImageView; + +import com.henninghall.date_picker.R; +import com.henninghall.date_picker.State; + +public class FadingOverlay { + + private final GradientDrawable gradientTop; + private final GradientDrawable gradientBottom; + private final State state; + + public FadingOverlay(State state, View rootView) { + this.state = state; + ImageView overlayTop = (ImageView) rootView.findViewById(R.id.overlay_top); + ImageView overlayBottom = (ImageView) rootView.findViewById(R.id.overlay_bottom); + gradientTop = (GradientDrawable) overlayTop.getDrawable(); + gradientBottom = (GradientDrawable) overlayBottom.getDrawable(); + } + + public void updateColor(){ + String color = state.getFadeToColor(); + int alpha = validColor(color) ? 255 : 0; + gradientTop.setAlpha(alpha); + gradientBottom.setAlpha(alpha); + if(validColor(color)) { + int startColor = Color.parseColor("#FF"+ color.substring(1)); + int endColor = Color.parseColor("#00" + color.substring(1)); + gradientTop.setColors(new int[] {startColor, endColor}); + gradientBottom.setColors(new int[] {startColor, endColor}); + } + } + + private boolean validColor(String color){ + return color != null && color.length() == 7; + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/ui/UIManager.java b/android/src/main/java/com/henninghall/date_picker/ui/UIManager.java new file mode 100644 index 0000000..7e6dfe6 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/UIManager.java @@ -0,0 +1,87 @@ +package com.henninghall.date_picker.ui; + +import android.view.View; + +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; +import com.henninghall.date_picker.wheelFunctions.AnimateToDate; +import com.henninghall.date_picker.wheelFunctions.Refresh; +import com.henninghall.date_picker.wheelFunctions.SetDate; +import com.henninghall.date_picker.wheelFunctions.SetShowCount; +import com.henninghall.date_picker.wheelFunctions.TextColor; +import com.henninghall.date_picker.wheelFunctions.UpdateVisibility; +import com.henninghall.date_picker.wheels.Wheel; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + +public class UIManager { + private final State state; + private final View rootView; + private Wheels wheels; + private FadingOverlay fadingOverlay; + private WheelScroller wheelScroller = new WheelScroller(); + + public UIManager(State state, View rootView){ + this.rootView = rootView; + this.state = state; + wheels = new Wheels(state, rootView, this); + fadingOverlay = new FadingOverlay(state, rootView); + } + + public void updateWheelVisibility(){ + wheels.applyOnAll(new UpdateVisibility()); + } + + public void updateTextColor(){ + wheels.applyOnAll(new TextColor(state.getTextColor())); + } + + public void updateFadeToColor(){ + fadingOverlay.updateColor(); + } + + public void updateHeight(){ + int shownCount = state.getShownCount(); + wheels.applyOnAll(new SetShowCount(shownCount)); + setShownCountOnEmptyWheels(shownCount); + } + + public void updateWheelOrder() { + wheels.removeAll(); + wheels.addInOrder(); + wheels.addEmpty(); + } + + public void updateDisplayValues(){ + wheels.applyOnAll(new Refresh()); + } + + public void setWheelsToDate(){ + wheels.applyOnAll(new SetDate(state.getDate())); + } + + public void scroll(int wheelIndex, int scrollTimes) { + Wheel wheel = wheels.getWheel(state.getOrderedVisibleWheels().get(wheelIndex)); + wheelScroller.scroll(wheel,scrollTimes); + } + + SimpleDateFormat getDateFormat() { + return new SimpleDateFormat(wheels.getFormatPattern(), state.getLocale()); + } + + void animateToDate(Calendar date) { + wheels.applyOnVisible(new AnimateToDate(date)); + } + + private void setShownCountOnEmptyWheels(int shownCount) { + for (int id : Utils.emptyWheelIds) { + NumberPickerView view = (NumberPickerView) rootView.findViewById(id); + if(view != null) view.setShownCount(shownCount); + } + } + + +} diff --git a/android/src/main/java/com/henninghall/date_picker/WheelChangeListener.java b/android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListener.java similarity index 76% rename from android/src/main/java/com/henninghall/date_picker/WheelChangeListener.java rename to android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListener.java index c0f83dd..c796347 100644 --- a/android/src/main/java/com/henninghall/date_picker/WheelChangeListener.java +++ b/android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListener.java @@ -1,4 +1,4 @@ -package com.henninghall.date_picker; +package com.henninghall.date_picker.ui; import com.henninghall.date_picker.wheels.Wheel; diff --git a/android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java b/android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java new file mode 100644 index 0000000..7b6df4c --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java @@ -0,0 +1,60 @@ +package com.henninghall.date_picker.ui; + +import android.view.View; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.RCTEventEmitter; +import com.henninghall.date_picker.DatePickerManager; +import com.henninghall.date_picker.PickerView; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; +import com.henninghall.date_picker.wheels.Wheel; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +public class WheelChangeListenerImpl implements WheelChangeListener { + + private final Wheels wheels; + private final State state; + private final UIManager uiManager; + private final View rootView; + + public WheelChangeListenerImpl(Wheels wheels, State state, UIManager uiManager, View rootView) { + this.wheels = wheels; + this.uiManager = uiManager; + this.state = state; + this.rootView = rootView; + } + + @Override + public void onChange(Wheel picker) { + WritableMap event = Arguments.createMap(); + TimeZone timeZone = state.getTimeZone(); + SimpleDateFormat dateFormat = uiManager.getDateFormat(); + Calendar minDate = state.getMinimumDate(); + Calendar maxDate = state.getMaximumDate(); + try { + dateFormat.setTimeZone(timeZone); + Calendar date = Calendar.getInstance(timeZone); + String toParse = wheels.getDateString(); + Date newDate = dateFormat.parse(toParse); + date.setTime(newDate); + + if (minDate != null && date.before(minDate)) uiManager.animateToDate(minDate); + else if (maxDate != null && date.after(maxDate)) uiManager.animateToDate(maxDate); + else { + event.putString("date", Utils.dateToIso(date)); + DatePickerManager.context.getJSModule(RCTEventEmitter.class) + .receiveEvent(rootView.getId(), "dateChange", event); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } + +} diff --git a/android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java b/android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java new file mode 100644 index 0000000..18f2d73 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java @@ -0,0 +1,19 @@ +package com.henninghall.date_picker.ui; + +import com.henninghall.date_picker.wheels.Wheel; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + +public class WheelScroller { + + public void scroll(Wheel wheel, int scrollTimes) { + NumberPickerView picker = wheel.picker; + int currentIndex = picker.getValue(); + int maxValue = picker.getMaxValue(); + boolean isWrapping = picker.getWrapSelectorWheel(); + int nextValue = currentIndex + scrollTimes; + if(nextValue <= maxValue || isWrapping) { + picker.smoothScrollToValue(nextValue % (maxValue + 1)); + } + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java b/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java new file mode 100644 index 0000000..ccf24d7 --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/ui/Wheels.java @@ -0,0 +1,186 @@ +package com.henninghall.date_picker.ui; + +import android.view.View; +import android.widget.LinearLayout; + +import com.henninghall.date_picker.R; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; +import com.henninghall.date_picker.models.WheelType; +import com.henninghall.date_picker.models.Mode; +import com.henninghall.date_picker.wheelFunctions.AddOnChangeListener; +import com.henninghall.date_picker.wheelFunctions.WheelFunction; +import com.henninghall.date_picker.wheels.AmPmWheel; +import com.henninghall.date_picker.wheels.DateWheel; +import com.henninghall.date_picker.wheels.DayWheel; +import com.henninghall.date_picker.wheels.HourWheel; +import com.henninghall.date_picker.wheels.MinutesWheel; +import com.henninghall.date_picker.wheels.MonthWheel; +import com.henninghall.date_picker.wheels.Wheel; +import com.henninghall.date_picker.wheels.YearWheel; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + +public class Wheels { + + private final State state; + private HourWheel hourWheel; + private DayWheel dayWheel; + private MinutesWheel minutesWheel; + private AmPmWheel ampmWheel; + private DateWheel dateWheel; + private MonthWheel monthWheel; + private YearWheel yearWheel; + private View rootView; + private final LinearLayout wheelsWrapper; + private final EmptyWheels emptyWheels; + + private HashMap wheelPerWheelType; + private UIManager uiManager; + + Wheels(State state, View rootView, UIManager uiManager){ + this.state = state; + this.rootView = rootView; + this.uiManager = uiManager; + wheelsWrapper = (LinearLayout) rootView.findViewById(R.id.wheelsWrapper); + wheelsWrapper.setWillNotDraw(false); + + yearWheel = new YearWheel(getPickerWithId(R.id.year), state); + monthWheel = new MonthWheel(getPickerWithId(R.id.month), state); + dateWheel = new DateWheel(getPickerWithId(R.id.date), state); + dayWheel = new DayWheel(getPickerWithId(R.id.day), state); + minutesWheel = new MinutesWheel(getPickerWithId(R.id.minutes), state); + ampmWheel = new AmPmWheel(getPickerWithId(R.id.ampm), state); + hourWheel = new HourWheel(getPickerWithId(R.id.hour), state); + wheelPerWheelType = getWheelPerType(); + + changeAmPmWhenPassingMidnightOrNoon(); + addOnChangeListener(); + emptyWheels = new EmptyWheels(rootView,this,state); + } + + private void addOnChangeListener(){ + WheelChangeListener onWheelChangeListener = new WheelChangeListenerImpl(this, state, uiManager, rootView); + applyOnAll(new AddOnChangeListener(onWheelChangeListener)); + } + + private NumberPickerView getPickerWithId(int id){ + return (NumberPickerView) rootView.findViewById(id); + } + + private Collection getVisible() { + ArrayList wheelTypes = state.getVisibleWheels(); + Collection wheels = new ArrayList<>(); + for (WheelType type: wheelTypes){ + wheels.add(getWheel(type)); + } + return wheels; + } + + void applyOnAll(WheelFunction function) { + for (Wheel wheel: getAll()) function.apply(wheel); + } + + void applyOnVisible(WheelFunction function) { + for (Wheel wheel: getVisible()) function.apply(wheel); + } + + Wheel getWheel(WheelType type){ + return wheelPerWheelType.get(type); + } + + void addInOrder(){ + ArrayList wheels = state.getOrderedVisibleWheels(); + for (WheelType wheelType : wheels) { + Wheel wheel = getWheel(wheelType); + addWheel(wheel.picker); + } + } + + private ArrayList getOrderedWheels(){ + ArrayList list = new ArrayList<>(); + for (WheelType type : state.getOrderedVisibleWheels()) { + list.add(getWheel(type)); + } + return list; + } + + void addWheel(View wheel) { wheelsWrapper.addView(wheel); } + + void addWheel(View wheel, int index) { wheelsWrapper.addView(wheel,index); } + + void removeAll() { + wheelsWrapper.removeAllViews(); + } + + private void changeAmPmWhenPassingMidnightOrNoon() { + hourWheel.picker.setOnValueChangeListenerInScrolling(new NumberPickerView.OnValueChangeListenerInScrolling() { + @Override + public void onValueChangeInScrolling(NumberPickerView picker, int oldVal, int newVal) { + if(Utils.usesAmPm()){ + String oldValue = hourWheel.getValueAtIndex(oldVal); + String newValue = hourWheel.getValueAtIndex(newVal); + boolean passingNoonOrMidnight = (oldValue.equals("12") && newValue.equals("11")) || oldValue.equals("11") && newValue.equals("12"); + if (passingNoonOrMidnight) ampmWheel.picker.smoothScrollToValue((ampmWheel.picker.getValue() + 1) % 2,false); + } + } + }); + } + + private List getAll(){ + return new ArrayList<>(Arrays.asList(yearWheel, monthWheel, dateWheel, dayWheel, hourWheel, minutesWheel, ampmWheel)); + } + + private String getDateFormatPattern(){ + ArrayList wheels = getOrderedWheels(); + if(state.getMode() == Mode.date){ + return wheels.get(0).getFormatPattern() + " " + + wheels.get(1).getFormatPattern() + " " + + wheels.get(2).getFormatPattern(); + } + return dayWheel.getFormatPattern(); + } + + public String getFormatPattern() { + return this.getDateFormatPattern() + " " + + hourWheel.getFormatPattern() + " " + + minutesWheel.getFormatPattern() + + ampmWheel.getFormatPattern(); + } + + String getDateString() { + ArrayList wheels = getOrderedWheels(); + + String dateString = (state.getMode() == Mode.date) + ? wheels.get(0).getValue() + " " + + wheels.get(1).getValue() + " " + + wheels.get(2).getValue() + : dayWheel.getValue(); + return dateString + + " " + hourWheel.getValue() + + " " + minutesWheel.getValue() + + ampmWheel.getValue(); + } + + private HashMap getWheelPerType(){ + return new HashMap() {{ + put(WheelType.DAY, dayWheel); + put(WheelType.YEAR, yearWheel); + put(WheelType.MONTH,monthWheel); + put(WheelType.DATE, dateWheel); + put(WheelType.HOUR, hourWheel); + put(WheelType.MINUTE, minutesWheel); + put(WheelType.AM_PM, ampmWheel); + }}; + } + + void addEmpty() { + emptyWheels.add(); + } +} diff --git a/android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java b/android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java new file mode 100644 index 0000000..7b7f67d --- /dev/null +++ b/android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java @@ -0,0 +1,27 @@ +package com.henninghall.date_picker.wheelFunctions; + +import com.henninghall.date_picker.ui.WheelChangeListener; +import com.henninghall.date_picker.wheels.Wheel; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + +public class AddOnChangeListener implements WheelFunction { + + private final WheelChangeListener onChangeListener; + + public AddOnChangeListener(WheelChangeListener onChangeListener){ + this.onChangeListener = onChangeListener; + } + + @Override + public void apply(final Wheel wheel) { + wheel.picker.setOnValueChangedListener(new NumberPickerView.OnValueChangeListener() { + @Override + public void onValueChange(NumberPickerView picker, int oldVal, int newVal) { + onChangeListener.onChange(wheel); + } + }); + } +} + + diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java index b111c03..97a686c 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java @@ -2,18 +2,20 @@ package com.henninghall.date_picker.wheels; import android.graphics.Paint; -import com.henninghall.date_picker.Mode; -import com.henninghall.date_picker.PickerView; -import com.henninghall.date_picker.Settings; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; +import com.henninghall.date_picker.models.Mode; import java.util.ArrayList; import java.util.Calendar; +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + public class AmPmWheel extends Wheel { - public AmPmWheel(PickerView pickerView, int id) { - super(pickerView, id); + public AmPmWheel(final NumberPickerView picker, State state) { + super(picker, state); } @Override @@ -31,12 +33,12 @@ public class AmPmWheel extends Wheel { @Override public boolean visible() { - return Settings.usesAmPm() && pickerView.mode != Mode.date; + return Utils.usesAmPm() && state.getMode() != Mode.date; } @Override public String getFormatPattern() { - return Settings.usesAmPm() ? " a " : ""; + return Utils.usesAmPm() ? " a " : ""; } @Override diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java index 29f59a0..b875521 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java @@ -1,17 +1,17 @@ package com.henninghall.date_picker.wheels; import android.graphics.Paint; -import android.text.format.DateUtils; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.*; import com.henninghall.date_picker.*; +import com.henninghall.date_picker.models.Mode; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; public class DateWheel extends Wheel { - public DateWheel(final PickerView pickerView, final int id) { - super(pickerView, id); + public DateWheel(final NumberPickerView picker, final State id) { + super(picker, id); } @@ -32,12 +32,12 @@ public class DateWheel extends Wheel @Override public boolean visible() { - return this.pickerView.mode == Mode.date; + return state.getMode() == Mode.date; } @Override public String getFormatPattern() { - return LocaleUtils.getPatternIncluding("d", pickerView.locale); + return LocaleUtils.getPatternIncluding("d", state.getLocale()); } @Override 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 898c325..63cdc5e 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 @@ -4,7 +4,8 @@ import android.graphics.Paint; import android.text.TextUtils; import com.henninghall.date_picker.LocaleUtils; -import com.henninghall.date_picker.Mode; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.models.Mode; import com.henninghall.date_picker.PickerView; import com.henninghall.date_picker.Utils; @@ -12,15 +13,17 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + public class DayWheel extends Wheel { private String todayValue; + private static int defaultNumberOfDays = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_YEAR); - public DayWheel(PickerView pickerView, int id) { - super(pickerView, id); + public DayWheel(NumberPickerView picker, State state) { + super(picker, state); } - private static int defaultNumberOfDays = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_YEAR); @Override public ArrayList getValues() { @@ -40,8 +43,8 @@ public class DayWheel extends Wheel { private Calendar getStartCal(){ Calendar cal; - Calendar max = pickerView.getMaximumDate(); - Calendar min = pickerView.getMinimumDate(); + Calendar max = state.getMaximumDate(); + Calendar min = state.getMinimumDate(); if (min != null) { cal = (Calendar) min.clone(); resetToMidnight(cal); @@ -50,7 +53,7 @@ public class DayWheel extends Wheel { resetToMidnight(cal); cal.add(Calendar.DATE, -cal.getActualMaximum(Calendar.DAY_OF_YEAR) / 2); } else { - cal = (Calendar) pickerView.getInitialDate().clone(); + cal = (Calendar) state.getInitialDate().clone(); cal.add(Calendar.DATE, -defaultNumberOfDays / 2); } return cal; @@ -58,8 +61,8 @@ public class DayWheel extends Wheel { private Calendar getEndCal(){ Calendar cal; - Calendar max = pickerView.getMaximumDate(); - Calendar min = pickerView.getMinimumDate(); + Calendar max = state.getMaximumDate(); + Calendar min = state.getMinimumDate(); if (max != null) { cal = (Calendar) max.clone(); resetToMidnight(cal); @@ -68,7 +71,7 @@ public class DayWheel extends Wheel { resetToMidnight(cal); cal.add(Calendar.DATE, cal.getActualMaximum(Calendar.DAY_OF_YEAR) / 2); } else { - cal = (Calendar) pickerView.getInitialDate().clone(); + cal = (Calendar) state.getInitialDate().clone(); cal.setTime(new Date()); cal.add(Calendar.DATE, defaultNumberOfDays / 2); } @@ -88,13 +91,13 @@ public class DayWheel extends Wheel { @Override public boolean visible() { - return pickerView.mode == Mode.datetime; + return state.getMode() == Mode.datetime; } @Override public String getFormatPattern() { - return LocaleUtils.getDatePattern(pickerView.locale) + return LocaleUtils.getDatePattern(state.getLocale()) .replace("EEEE", "EEE") .replace("MMMM", "MMM"); } @@ -113,7 +116,7 @@ public class DayWheel extends Wheel { } private String toTodayString(String value) { - String todayString = Utils.printToday(pickerView.locale); + String todayString = Utils.printToday(state.getLocale()); boolean shouldBeCapitalized = Character.isUpperCase(value.charAt(0)); return shouldBeCapitalized ? Utils.capitalize(todayString) @@ -122,7 +125,7 @@ public class DayWheel extends Wheel { private String removeYear(String value) { ArrayList pieces = Utils.splitOnSpace(value); - pieces.remove(LocaleUtils.getFullPatternPos("y", pickerView.locale)); + pieces.remove(LocaleUtils.getFullPatternPos("y", state.getLocale())); return TextUtils.join(" ", pieces); } diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java index 2783bda..2ce30f3 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java @@ -2,25 +2,26 @@ package com.henninghall.date_picker.wheels; import android.graphics.Paint; -import com.henninghall.date_picker.Mode; -import com.henninghall.date_picker.PickerView; -import com.henninghall.date_picker.Settings; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.Utils; +import com.henninghall.date_picker.models.Mode; import java.util.ArrayList; import java.util.Calendar; +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + public class HourWheel extends Wheel { - public HourWheel(PickerView pickerView, int id) { - super(pickerView, id); + public HourWheel(NumberPickerView picker, State id) { + super(picker, id); } - @Override public ArrayList getValues() { Calendar cal = Calendar.getInstance(); ArrayList values = new ArrayList<>(); - int numberOfHours = Settings.usesAmPm() ? 12 : 24; + int numberOfHours = Utils.usesAmPm() ? 12 : 24; for(int i=0; i values = new ArrayList<>(); cal.set(Calendar.MINUTE, 0); - for(int i=0; i<60; i = i + pickerView.minuteInterval) { + for(int i=0; i<60; i = i + state.getMinuteInterval()) { values.add(format.format(cal.getTime())); - cal.add(Calendar.MINUTE, pickerView.minuteInterval); + cal.add(Calendar.MINUTE, state.getMinuteInterval()); } return values; @@ -31,7 +33,7 @@ public class MinutesWheel extends Wheel { @Override public boolean visible() { - return pickerView.mode != Mode.date; + return state.getMode() != Mode.date; } @Override @@ -41,7 +43,7 @@ public class MinutesWheel extends Wheel { @Override public Paint.Align getTextAlign() { - return Settings.usesAmPm() ? Paint.Align.RIGHT: Paint.Align.LEFT; + return Utils.usesAmPm() ? Paint.Align.RIGHT: Paint.Align.LEFT; } } diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java index 9a39dc7..05b17ef 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java @@ -4,10 +4,13 @@ import android.graphics.Paint; import java.util.*; import com.henninghall.date_picker.*; +import com.henninghall.date_picker.models.Mode; + +import cn.carbswang.android.numberpickerview.library.NumberPickerView; public class MonthWheel extends Wheel { - public MonthWheel(final PickerView pickerView, final int id) { + public MonthWheel(final NumberPickerView pickerView, final State id) { super(pickerView, id); } @@ -27,7 +30,7 @@ public class MonthWheel extends Wheel @Override public boolean visible() { - return this.pickerView.mode == Mode.date; + return state.getMode() == Mode.date; } @Override diff --git a/android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java b/android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java index 3cbdede..56a4128 100644 --- a/android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java +++ b/android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java @@ -4,7 +4,7 @@ import android.graphics.Paint; import android.view.View; import cn.carbswang.android.numberpickerview.library.NumberPickerView; -import com.henninghall.date_picker.PickerView; +import com.henninghall.date_picker.State; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -13,9 +13,7 @@ import java.util.Locale; public abstract class Wheel { - private final Wheel self; - public final int id; - public PickerView pickerView; + protected final State state; private Calendar userSetValue; public abstract boolean visible(); @@ -27,27 +25,19 @@ public abstract class Wheel { return value; } - ArrayList values = new ArrayList<>(); + private ArrayList values = new ArrayList<>(); public NumberPickerView picker; public SimpleDateFormat format; - public Wheel(final PickerView pickerView, final int id) { - this.id = id; - this.self = this; - this.pickerView = pickerView; - this.picker = (NumberPickerView) pickerView.findViewById(id); - this.format = new SimpleDateFormat(getFormatPattern(), pickerView.locale); + public Wheel(NumberPickerView picker, State state) { + this.state = state; + this.picker = picker; + this.format = new SimpleDateFormat(getFormatPattern(), state.getLocale()); picker.setTextAlign(getTextAlign()); - picker.setOnValueChangedListener(new NumberPickerView.OnValueChangeListener() { - @Override - public void onValueChange(NumberPickerView picker, int oldVal, int newVal) { - pickerView.getListener().onChange(self); - } - }); } private int getIndexOfDate(Calendar date){ - format.setTimeZone(pickerView.timeZone); + format.setTimeZone(state.getTimeZone()); return values.indexOf(format.format(date.getTime())); } @@ -69,7 +59,7 @@ public abstract class Wheel { } public void setValue(Calendar date) { - format.setTimeZone(pickerView.timeZone); + format.setTimeZone(state.getTimeZone()); this.userSetValue = date; int index = getIndexOfDate(date); @@ -81,7 +71,7 @@ public abstract class Wheel { } public void refresh() { - this.format = new SimpleDateFormat(getFormatPattern(), pickerView.locale); + this.format = new SimpleDateFormat(getFormatPattern(), state.getLocale()); if (!this.visible()) return; init(); } @@ -112,7 +102,7 @@ public abstract class Wheel { } String getLocaleString(Calendar cal) { - return getString(cal, this.pickerView.locale); + return getString(cal, this.state.getLocale()); } private String getString(Calendar cal, Locale locale){ 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 295e434..ceb6863 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 @@ -3,19 +3,22 @@ package com.henninghall.date_picker.wheels; import android.graphics.Paint; import com.henninghall.date_picker.LocaleUtils; -import com.henninghall.date_picker.Mode; +import com.henninghall.date_picker.State; +import com.henninghall.date_picker.models.Mode; import com.henninghall.date_picker.PickerView; import java.util.ArrayList; import java.util.Calendar; +import cn.carbswang.android.numberpickerview.library.NumberPickerView; + public class YearWheel extends Wheel { private int defaultStartYear; private int defaultEndYear; - public YearWheel(final PickerView pickerView, final int id) { - super(pickerView, id); + public YearWheel(final NumberPickerView picker, final State id) { + super(picker, id); this.defaultStartYear = 1900; this.defaultEndYear = 2100; } @@ -40,22 +43,22 @@ public class YearWheel extends Wheel } private int getEndYear() { - if (this.pickerView.getMaximumDate() == null) { + if (state.getMaximumDate() == null) { return this.defaultEndYear; } - return this.pickerView.getMaximumDate().get(Calendar.YEAR); + return state.getMaximumDate().get(Calendar.YEAR); } private int getStartYear() { - if (this.pickerView.getMinimumDate() == null) { + if (state.getMinimumDate() == null) { return this.defaultStartYear; } - return this.pickerView.getMinimumDate().get(Calendar.YEAR); + return state.getMinimumDate().get(Calendar.YEAR); } @Override public boolean visible() { - return this.pickerView.mode == Mode.date; + return state.getMode() == Mode.date; } @Override @@ -65,7 +68,7 @@ public class YearWheel extends Wheel @Override public String getFormatPattern() { - return LocaleUtils.getPatternIncluding("y", pickerView.locale); + return LocaleUtils.getPatternIncluding("y", state.getLocale()); } }