Browse Source

Improved architecture

Separating concerns
Remove duplicated code
master
Henning Hall 5 years ago
parent
commit
9edc7bcc8e
40 changed files with 1046 additions and 641 deletions
  1. +4
    -2
      android/src/main/java/com/henninghall/date_picker/DateBoundary.java
  2. +45
    -70
      android/src/main/java/com/henninghall/date_picker/DatePickerManager.java
  3. +0
    -42
      android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java
  4. +57
    -203
      android/src/main/java/com/henninghall/date_picker/PickerView.java
  5. +0
    -12
      android/src/main/java/com/henninghall/date_picker/Settings.java
  6. +206
    -0
      android/src/main/java/com/henninghall/date_picker/State.java
  7. +0
    -61
      android/src/main/java/com/henninghall/date_picker/Style.java
  8. +7
    -0
      android/src/main/java/com/henninghall/date_picker/Utils.java
  9. +0
    -56
      android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java
  10. +0
    -109
      android/src/main/java/com/henninghall/date_picker/WheelOrder.java
  11. +0
    -5
      android/src/main/java/com/henninghall/date_picker/WheelPosition.java
  12. +1
    -1
      android/src/main/java/com/henninghall/date_picker/models/Mode.java
  13. +1
    -1
      android/src/main/java/com/henninghall/date_picker/models/WheelType.java
  14. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/DateProp.java
  15. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java
  16. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/HeightProp.java
  17. +28
    -0
      android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java
  18. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java
  19. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java
  20. +17
    -0
      android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java
  21. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/ModeProp.java
  22. +28
    -0
      android/src/main/java/com/henninghall/date_picker/props/Prop.java
  23. +13
    -0
      android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java
  24. +12
    -0
      android/src/main/java/com/henninghall/date_picker/props/UtcProp.java
  25. +45
    -0
      android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java
  26. +42
    -0
      android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java
  27. +87
    -0
      android/src/main/java/com/henninghall/date_picker/ui/UIManager.java
  28. +1
    -1
      android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListener.java
  29. +60
    -0
      android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java
  30. +19
    -0
      android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java
  31. +186
    -0
      android/src/main/java/com/henninghall/date_picker/ui/Wheels.java
  32. +27
    -0
      android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java
  33. +9
    -7
      android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java
  34. +7
    -7
      android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java
  35. +17
    -14
      android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java
  36. +10
    -9
      android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java
  37. +11
    -9
      android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java
  38. +5
    -2
      android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java
  39. +11
    -21
      android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java
  40. +12
    -9
      android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java

+ 4
- 2
android/src/main/java/com/henninghall/date_picker/DateBoundary.java View File

@ -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);
}

+ 45
- 70
android/src/main/java/com/henninghall/date_picker/DatePickerManager.java View File

@ -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<PickerView> {
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<String, Integer> 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);
}
}

+ 0
- 42
android/src/main/java/com/henninghall/date_picker/EmptyWheelUpdater.java View File

@ -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<Integer, NumberPickerView> views;
EmptyWheelUpdater(PickerView pickerView) {
this.pickerView = pickerView;
this.views = getViews();
}
private HashMap<Integer, NumberPickerView> getViews() {
HashMap<Integer, NumberPickerView> 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);
}
}
}

+ 57
- 203
android/src/main/java/com/henninghall/date_picker/PickerView.java View File

@ -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<String> 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<String> nonRefreshingProps = new ArrayList<String>(){{
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<Wheel> getVisibleWheels() {
Collection<Wheel> 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<Wheel> 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));
}
}
}

+ 0
- 12
android/src/main/java/com/henninghall/date_picker/Settings.java View File

@ -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);
}
}

+ 206
- 0
android/src/main/java/com/henninghall/date_picker/State.java View File

@ -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<String, Prop>() {{
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<WheelType> getOrderedWheels() {
String dateTimePattern = LocaleUtils.getDateTimePattern(getLocale());
ArrayList<WheelType> unorderedTypes = new ArrayList(Arrays.asList(WheelType.values()));
ArrayList<WheelType> 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<WheelType> getVisibleWheels() {
ArrayList<WheelType> 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<WheelType> getOrderedVisibleWheels() {
ArrayList<WheelType> orderedWheels = getOrderedWheels();
ArrayList<WheelType> visibleWheels = getVisibleWheels();
ArrayList<WheelType> 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);
}
}

+ 0
- 61
android/src/main/java/com/henninghall/date_picker/Style.java View File

@ -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;
}
}

+ 7
- 0
android/src/main/java/com/henninghall/date_picker/Utils.java View File

@ -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,

+ 0
- 56
android/src/main/java/com/henninghall/date_picker/WheelChangeListenerImpl.java View File

@ -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();
}
}
}

+ 0
- 109
android/src/main/java/com/henninghall/date_picker/WheelOrder.java View File

@ -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<WheelType, Wheel> wheelPerWheelType;
private PickerView pickerView;
private ArrayList<WheelType> orderedWheels;
WheelOrder(final PickerView view) {
this.pickerView = view;
this.wheelPerWheelType = new HashMap<WheelType, Wheel>() {{
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<Wheel> getVisibleWheels() {
ArrayList<Wheel> visibleOrderedWheels = new ArrayList<>();
for (WheelType wheelType : orderedWheels){
Wheel wheel = wheelPerWheelType.get(wheelType);
if(wheel.visible()) {
visibleOrderedWheels.add(wheel);
}
}
return visibleOrderedWheels;
}
private ArrayList<WheelType> getOrderedWheels(Locale locale) throws Exception {
String dateTimePattern = LocaleUtils.getDateTimePattern(locale);
ArrayList<WheelType> unorderedTypes = new ArrayList(Arrays.asList(WheelType.values()));
ArrayList<WheelType> 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;
}
}

+ 0
- 5
android/src/main/java/com/henninghall/date_picker/WheelPosition.java View File

@ -1,5 +0,0 @@
package com.henninghall.date_picker;
public enum WheelPosition {
LEFT, RIGHT, MIDDLE
}

android/src/main/java/com/henninghall/date_picker/Mode.java → android/src/main/java/com/henninghall/date_picker/models/Mode.java View File

@ -1,4 +1,4 @@
package com.henninghall.date_picker;
package com.henninghall.date_picker.models;
public enum Mode {
date, time, datetime

android/src/main/java/com/henninghall/date_picker/WheelType.java → android/src/main/java/com/henninghall/date_picker/models/WheelType.java View File

@ -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

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/DateProp.java View File

@ -0,0 +1,13 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class DateProp extends Prop<String> {
public static final String name = "date";
@Override
public String toValue(Dynamic value){
return value.asString();
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/FadeToColorProp.java View File

@ -0,0 +1,13 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class FadeToColorProp extends Prop<String> {
public static final String name = "fadeToColor";
@Override
public String toValue(Dynamic value){
return value.asString();
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/HeightProp.java View File

@ -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<Integer> {
public static final String name = "height";
@Override
public Integer toValue(Dynamic value){
return value.asInt();
}
}

+ 28
- 0
android/src/main/java/com/henninghall/date_picker/props/LocaleProp.java View File

@ -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<Locale> {
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('-','_'));
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/MaximumDateProp.java View File

@ -0,0 +1,13 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class MaximumDateProp extends Prop<String> {
public static final String name = "maximumDate";
@Override
public String toValue(Dynamic value){
return value.asString();
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/MinimumDateProp.java View File

@ -0,0 +1,13 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class MinimumDateProp extends Prop<String> {
public static final String name = "minimumDate";
@Override
public String toValue(Dynamic value){
return value.asString();
}
}

+ 17
- 0
android/src/main/java/com/henninghall/date_picker/props/MinuteIntervalProp.java View File

@ -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<Integer> {
public static final String name = "minuteInterval";
public MinuteIntervalProp(){
super(1);
}
public Integer toValue(Dynamic value){
return value.asInt();
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/ModeProp.java View File

@ -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<Mode> {
public static final String name = "mode";
@Override
public Mode toValue(Dynamic value){
return Mode.valueOf(value.asString());
}
}

+ 28
- 0
android/src/main/java/com/henninghall/date_picker/props/Prop.java View File

@ -0,0 +1,28 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public abstract class Prop<T> {
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;
}
}

+ 13
- 0
android/src/main/java/com/henninghall/date_picker/props/TextColorProp.java View File

@ -0,0 +1,13 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class TextColorProp extends Prop<String> {
public static final String name = "textColor";
@Override
public String toValue(Dynamic value){
return value.asString();
}
}

+ 12
- 0
android/src/main/java/com/henninghall/date_picker/props/UtcProp.java View File

@ -0,0 +1,12 @@
package com.henninghall.date_picker.props;
import com.facebook.react.bridge.Dynamic;
public class UtcProp extends Prop<Boolean> {
public static final String name = "utc";
@Override
Boolean toValue(Dynamic value) {
return value.asBoolean();
}
}

+ 45
- 0
android/src/main/java/com/henninghall/date_picker/ui/EmptyWheels.java View File

@ -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<Integer, NumberPickerView> 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<Integer, NumberPickerView> getViews() {
HashMap<Integer, NumberPickerView> 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);
}
}
}

+ 42
- 0
android/src/main/java/com/henninghall/date_picker/ui/FadingOverlay.java View File

@ -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;
}
}

+ 87
- 0
android/src/main/java/com/henninghall/date_picker/ui/UIManager.java View File

@ -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);
}
}
}

android/src/main/java/com/henninghall/date_picker/WheelChangeListener.java → android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListener.java View File

@ -1,4 +1,4 @@
package com.henninghall.date_picker;
package com.henninghall.date_picker.ui;
import com.henninghall.date_picker.wheels.Wheel;

+ 60
- 0
android/src/main/java/com/henninghall/date_picker/ui/WheelChangeListenerImpl.java View File

@ -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();
}
}
}

+ 19
- 0
android/src/main/java/com/henninghall/date_picker/ui/WheelScroller.java View File

@ -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));
}
}
}

+ 186
- 0
android/src/main/java/com/henninghall/date_picker/ui/Wheels.java View File

@ -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<WheelType, Wheel> 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<Wheel> getVisible() {
ArrayList<WheelType> wheelTypes = state.getVisibleWheels();
Collection<Wheel> 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<WheelType> wheels = state.getOrderedVisibleWheels();
for (WheelType wheelType : wheels) {
Wheel wheel = getWheel(wheelType);
addWheel(wheel.picker);
}
}
private ArrayList<Wheel> getOrderedWheels(){
ArrayList<Wheel> 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<Wheel> getAll(){
return new ArrayList<>(Arrays.asList(yearWheel, monthWheel, dateWheel, dayWheel, hourWheel, minutesWheel, ampmWheel));
}
private String getDateFormatPattern(){
ArrayList<Wheel> 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<Wheel> 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<WheelType, Wheel> getWheelPerType(){
return new HashMap<WheelType, Wheel>() {{
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();
}
}

+ 27
- 0
android/src/main/java/com/henninghall/date_picker/wheelFunctions/AddOnChangeListener.java View File

@ -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);
}
});
}
}

+ 9
- 7
android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java View File

@ -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

+ 7
- 7
android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java View File

@ -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

+ 17
- 14
android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java View File

@ -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<String> 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<String> pieces = Utils.splitOnSpace(value);
pieces.remove(LocaleUtils.getFullPatternPos("y", pickerView.locale));
pieces.remove(LocaleUtils.getFullPatternPos("y", state.getLocale()));
return TextUtils.join(" ", pieces);
}

+ 10
- 9
android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java View File

@ -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<String> getValues() {
Calendar cal = Calendar.getInstance();
ArrayList<String> values = new ArrayList<>();
int numberOfHours = Settings.usesAmPm() ? 12 : 24;
int numberOfHours = Utils.usesAmPm() ? 12 : 24;
for(int i=0; i<numberOfHours; i++) {
values.add(format.format(cal.getTime()));
@ -31,12 +32,12 @@ public class HourWheel extends Wheel {
@Override
public boolean visible() {
return pickerView.mode != Mode.date;
return state.getMode() != Mode.date;
}
@Override
public String getFormatPattern() {
return Settings.usesAmPm() ? "h": "HH";
return Utils.usesAmPm() ? "h": "HH";
}
@Override

+ 11
- 9
android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java View File

@ -2,17 +2,19 @@ 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 MinutesWheel extends Wheel {
public MinutesWheel(PickerView pickerView, int id) {
super(pickerView, id);
public MinutesWheel(NumberPickerView picker, State id) {
super(picker, id);
}
@Override
@ -21,9 +23,9 @@ public class MinutesWheel extends Wheel {
ArrayList<String> 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;
}
}

+ 5
- 2
android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java View File

@ -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

+ 11
- 21
android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java View File

@ -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<String> values = new ArrayList<>();
private ArrayList<String> 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){

+ 12
- 9
android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java View File

@ -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());
}
}

Loading…
Cancel
Save