Browse Source

Date mode

WIP: Year fixes.

Date mode.
master
Henning Hall 7 years ago
parent
commit
a1e3477bb4
28 changed files with 927 additions and 38 deletions
  1. +3
    -2
      android/src/main/java/com/henninghall/date_picker/DatePickerManager.java
  2. +39
    -20
      android/src/main/java/com/henninghall/date_picker/PickerView.java
  3. +17
    -0
      android/src/main/java/com/henninghall/date_picker/Utils.java
  4. +66
    -0
      android/src/main/java/com/henninghall/date_picker/WheelOrderUpdater.java
  5. +11
    -1
      android/src/main/java/com/henninghall/date_picker/wheelFunctions/Refresh.java
  6. +2
    -2
      android/src/main/java/com/henninghall/date_picker/wheels/AmPmWheel.java
  7. +39
    -0
      android/src/main/java/com/henninghall/date_picker/wheels/DateWheel.java
  8. +2
    -2
      android/src/main/java/com/henninghall/date_picker/wheels/DayWheel.java
  9. +2
    -2
      android/src/main/java/com/henninghall/date_picker/wheels/HourWheel.java
  10. +2
    -2
      android/src/main/java/com/henninghall/date_picker/wheels/MinutesWheel.java
  11. +39
    -0
      android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java
  12. +7
    -3
      android/src/main/java/com/henninghall/date_picker/wheels/Wheel.java
  13. +63
    -0
      android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java
  14. +42
    -0
      android/src/main/res/layout/datepicker_view.xml
  15. +2
    -1
      example/android/build.gradle
  16. +2
    -2
      example/android/gradle/wrapper/gradle-wrapper.properties
  17. +1
    -0
      example/src/exampleKeys.js
  18. +5
    -0
      example/src/examples.js
  19. +1
    -1
      example/src/examples/Advanced.js
  20. +17
    -0
      example/src/examples/DateMode.js
  21. +82
    -0
      temp/DatePickerManager.java
  22. +38
    -0
      temp/DateWheel.java
  23. +9
    -0
      temp/Mode.java
  24. +38
    -0
      temp/MonthWheel.java
  25. +184
    -0
      temp/PickerView.java
  26. +100
    -0
      temp/Wheel.java
  27. +56
    -0
      temp/WheelOrderUpdater.java
  28. +58
    -0
      temp/YearWheel.java

+ 3
- 2
android/src/main/java/com/henninghall/date_picker/DatePickerManager.java View File

@ -33,12 +33,13 @@ public class DatePickerManager extends SimpleViewManager {
@ReactProp(name = "mode")
public void setMode(PickerView view, @Nullable String mode) {
Mode m;
try {
view.setMode(Mode.valueOf(mode));
m = Mode.valueOf(mode);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid mode. Valid modes: 'datetime', 'date', 'time'");
}
view.setMode(m);
}
@ReactProp(name = "date")

+ 39
- 20
android/src/main/java/com/henninghall/date_picker/PickerView.java View File

@ -11,10 +11,13 @@ import com.henninghall.date_picker.wheelFunctions.Refresh;
import com.henninghall.date_picker.wheelFunctions.SetDate;
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 org.apache.commons.lang3.time.DateUtils;
@ -33,41 +36,41 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class PickerView extends RelativeLayout {
private final NumberPickerView hourPicker;
private final NumberPickerView ampmPicker;
private SimpleDateFormat dateFormat;
private HourWheel hourWheel;
private DayWheel dayWheel;
public MinutesWheel minutesWheel;
private AmPmWheel ampmWheel;
private Date minDate;
private Date maxDate;
public int minuteInterval = 1;
public Locale locale;
public Mode mode;
public Style style;
public DateWheel dateWheel;
public MonthWheel monthWheel;
public YearWheel yearWheel;
public Date maxDate;
public Date minDate;
private WheelOrderUpdater wheelOrderUpdater;
public PickerView() {
super(DatePickerManager.context);
View rootView = inflate(getContext(), R.layout.datepicker_view, this);
this.style = new Style(this);
this.wheelOrderUpdater = new WheelOrderUpdater(this);
RelativeLayout wheelsWrapper = (RelativeLayout) rootView.findViewById(R.id.wheelsWrapper);
wheelsWrapper.setWillNotDraw(false);
locale = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP ? Locale.forLanguageTag("en") : Locale.getDefault();
NumberPickerView dayPicker = (NumberPickerView) rootView.findViewById(R.id.day);
dayWheel = new DayWheel(dayPicker, this);
yearWheel = new YearWheel( this, R.id.year);
monthWheel = new MonthWheel( this, R.id.month);
dateWheel = new DateWheel( this, R.id.date);
NumberPickerView minutePicker = (NumberPickerView) rootView.findViewById(R.id.minutes);
minutesWheel = new MinutesWheel(minutePicker, this);
ampmPicker = (NumberPickerView) rootView.findViewById(R.id.ampm);
ampmWheel = new AmPmWheel(ampmPicker, this);
hourPicker = (NumberPickerView) rootView.findViewById(R.id.hour);
hourWheel = new HourWheel(hourPicker,this);
dayWheel = new DayWheel( this, R.id.day);
minutesWheel = new MinutesWheel( this, R.id.minutes);
ampmWheel = new AmPmWheel(this, R.id.ampm);
hourWheel = new HourWheel(this, R.id.hour);
dateFormat = new SimpleDateFormat(getDateFormatTemplate(), Locale.US);
changeAmPmWhenPassingMidnightOrNoon();
@ -78,6 +81,9 @@ public class PickerView extends RelativeLayout {
public void onChange(Wheel wheel) {
WritableMap event = Arguments.createMap();
try {
String pattern = dateFormat.toPattern();
String dateString = getDateString();
Date date = dateFormat.parse(getDateString());
if (minDate != null && date.before(minDate)) applyOnVisibleWheels(new AnimateToDate(minDate));
else if (maxDate != null && date.after(maxDate)) applyOnVisibleWheels(new AnimateToDate(maxDate));
@ -102,14 +108,14 @@ public class PickerView extends RelativeLayout {
};
private void changeAmPmWhenPassingMidnightOrNoon(){
hourPicker.setOnValueChangeListenerInScrolling(new NumberPickerView.OnValueChangeListenerInScrolling() {
hourWheel.picker.setOnValueChangeListenerInScrolling(new NumberPickerView.OnValueChangeListenerInScrolling() {
@Override
public void onValueChangeInScrolling(NumberPickerView picker, int oldVal, int newVal) {
if(Utils.usesAmPm(locale)){
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) ampmPicker.smoothScrollToValue((ampmPicker.getValue() + 1) % 2,false);
if (passingNoonOrMidnight) ampmWheel.picker.smoothScrollToValue((ampmWheel.picker.getValue() + 1) % 2,false);
}
}
});
@ -130,6 +136,7 @@ public class PickerView extends RelativeLayout {
public void setLocale(Locale locale) {
this.locale = locale;
dateFormat = new SimpleDateFormat(getDateFormatTemplate(), Locale.US);
wheelOrderUpdater.update(locale, mode);
applyOnAllWheels(new Refresh());
}
@ -153,14 +160,24 @@ public class PickerView extends RelativeLayout {
}
private String getDateFormatTemplate() {
return dayWheel.getFormatTemplate() + " "
String dateTemplate = (mode == Mode.date)
? (yearWheel.getFormatTemplate() + " "
+ monthWheel.getFormatTemplate() + " "
+ dateWheel.getFormatTemplate())
: dayWheel.getFormatTemplate();
return dateTemplate + " "
+ hourWheel.getFormatTemplate() + " "
+ minutesWheel.getFormatTemplate()
+ ampmWheel.getFormatTemplate();
}
private String getDateString() {
return dayWheel.getValue()
String dateString= (mode == Mode.date)
? (yearWheel.getValue() + " "
+ monthWheel.getValue() + " "
+ dateWheel.getValue())
: dayWheel.getValue();
return dateString
+ " " + hourWheel.getValue()
+ " " + minutesWheel.getValue()
+ ampmWheel.getValue();
@ -168,7 +185,9 @@ public class PickerView extends RelativeLayout {
public void setMode(Mode mode) {
this.mode = mode;
applyOnAllWheels(new Refresh());
dateFormat = new SimpleDateFormat(getDateFormatTemplate(), Locale.US);
applyOnAllWheels(new Refresh(false));
wheelOrderUpdater.update(locale, mode);
}
public Collection<Wheel> getVisibleWheels() {
@ -178,7 +197,7 @@ public class PickerView extends RelativeLayout {
}
public List<Wheel> getAllWheels(){
return new ArrayList<>(Arrays.asList(dayWheel, hourWheel, minutesWheel, ampmWheel));
return new ArrayList<>(Arrays.asList(yearWheel, monthWheel, dateWheel, dayWheel, hourWheel, minutesWheel, ampmWheel));
}
public void applyOnAllWheels(WheelFunction function) {

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

@ -1,6 +1,9 @@
package com.henninghall.date_picker;
import android.util.TypedValue;
import android.view.View;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -21,4 +24,18 @@ public class Utils {
return new Date((long)date);
}
public static int getWheelHeight(View pickerView) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 160, pickerView.getResources().getDisplayMetrics());
}
public static String localeToYmdPattern(Locale locale) {
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, locale);
String pattern = ((SimpleDateFormat)formatter).toLocalizedPattern();
pattern = pattern.replaceAll("\\[", "");
pattern = pattern.replaceAll("]", "");
pattern = pattern.replaceAll(" ", "");
pattern = pattern.replaceAll("[.]", "/");
pattern = pattern.replaceAll("-", "/");
return pattern;
}
}

+ 66
- 0
android/src/main/java/com/henninghall/date_picker/WheelOrderUpdater.java View File

@ -0,0 +1,66 @@
package com.henninghall.date_picker;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.henninghall.date_picker.wheels.Wheel;
import java.util.ArrayList;
import java.util.Locale;
public class WheelOrderUpdater
{
private final PickerView pickerView;
private String ymdPattern = "";
WheelOrderUpdater(final PickerView v) {
this.pickerView = v;
}
public void update(final Locale locale, final Mode mode) {
if (mode != Mode.date) {
return;
}
String lastYmdPattern = ymdPattern;
ymdPattern = Utils.localeToYmdPattern(locale);
if(lastYmdPattern.equals(ymdPattern)) return;
final ArrayList<Wheel> wheelOrder = this.ymdPatternToWheelOrder(ymdPattern);
this.placeWheelRightOf(wheelOrder.get(0), wheelOrder.get(1));
this.placeWheelRightOf(wheelOrder.get(1), wheelOrder.get(2));
}
private void placeWheelRightOf(final Wheel leftWheel, final Wheel rightWheel) {
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, Utils.getWheelHeight((View)this.pickerView));
params.addRule(1, leftWheel.id);
if (Build.VERSION.SDK_INT >= 17) {
params.addRule(17, leftWheel.id);
}
rightWheel.picker.setLayoutParams((ViewGroup.LayoutParams)params);
}
private ArrayList<Wheel> ymdPatternToWheelOrder(final String ymdPattern) {
final String[] parts = ymdPattern.split("/");
final ArrayList<Wheel> wheelList = new ArrayList<Wheel>();
for (final String s : parts) {
switch (s.charAt(0)) {
case 'y': {
wheelList.add(this.pickerView.yearWheel);
break;
}
case 'M': {
wheelList.add(this.pickerView.monthWheel);
break;
}
case 'd': {
wheelList.add(this.pickerView.dateWheel);
break;
}
}
}
return wheelList;
}
}

+ 11
- 1
android/src/main/java/com/henninghall/date_picker/wheelFunctions/Refresh.java View File

@ -4,9 +4,19 @@ import com.henninghall.date_picker.wheels.Wheel;
public class Refresh implements WheelFunction {
private final boolean keepOldValue;
public Refresh() {
this.keepOldValue = true;
}
public Refresh(boolean keepOldValue){
this.keepOldValue = keepOldValue;
}
@Override
public void apply(Wheel wheel) {
wheel.refresh(true);
wheel.refresh(keepOldValue);
}
}

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

@ -9,8 +9,8 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class AmPmWheel extends Wheel {
public AmPmWheel(NumberPickerView ampmPicker, PickerView pickerView) {
super(ampmPicker, pickerView);
public AmPmWheel(PickerView pickerView, int id) {
super(pickerView, id);
}
@Override

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

@ -0,0 +1,39 @@
package com.henninghall.date_picker.wheels;
import java.util.*;
import com.henninghall.date_picker.*;
public class DateWheel extends Wheel
{
public DateWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
}
@Override
void init() {
final int maxDate = 31;
final int minDate = 1;
final Calendar cal = this.pickerView.getInitialDate();
final String initialDate = this.format.format(cal.getTime());
for (int i = minDate; i <= maxDate; ++i) {
final int currentDate = (Integer.valueOf(initialDate) + i) % maxDate + 1;
final String currentDateString = String.valueOf(currentDate);
this.values.add(currentDateString);
this.displayValues.add(currentDateString);
}
this.picker.setDisplayedValues((String[])this.displayValues.toArray(new String[0]));
this.picker.setMinValue(0);
this.picker.setMaxValue(maxDate - minDate);
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
@Override
public String getFormatTemplate() {
return "d";
}
}

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

@ -13,8 +13,8 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class DayWheel extends Wheel {
public DayWheel(NumberPickerView dayPicker, PickerView pickerView) {
super(dayPicker, pickerView);
public DayWheel(PickerView pickerView, int id) {
super(pickerView, id);
}
@Override

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

@ -10,8 +10,8 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class HourWheel extends Wheel {
public HourWheel(NumberPickerView hourPicker, PickerView pickerView) {
super(hourPicker, pickerView);
public HourWheel(PickerView pickerView, int id) {
super(pickerView, id);
}
@Override

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

@ -10,8 +10,8 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public class MinutesWheel extends Wheel {
public MinutesWheel(NumberPickerView minutePicker, PickerView pickerView) {
super(minutePicker, pickerView);
public MinutesWheel(PickerView pickerView, int id) {
super(pickerView, id);
}
@Override

+ 39
- 0
android/src/main/java/com/henninghall/date_picker/wheels/MonthWheel.java View File

@ -0,0 +1,39 @@
package com.henninghall.date_picker.wheels;
import java.text.*;
import java.util.*;
import com.henninghall.date_picker.*;
public class MonthWheel extends Wheel
{
public MonthWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
}
@Override
void init() {
final int min = 0;
final int max = 12;
final Calendar cal = this.pickerView.getInitialDate();
final SimpleDateFormat format = new SimpleDateFormat(this.getFormatTemplate(), this.pickerView.locale);
for (int i = min; i <= max; ++i) {
this.values.add(format.format(cal.getTime()));
this.displayValues.add(format.format(cal.getTime()));
cal.add(2, 1);
}
this.picker.setDisplayedValues((String[])this.displayValues.toArray(new String[0]));
this.picker.setMinValue(0);
this.picker.setMaxValue(max);
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
@Override
public String getFormatTemplate() {
return "LLLL";
}
}

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

@ -2,6 +2,8 @@ package com.henninghall.date_picker.wheels;
import android.view.View;
import com.henninghall.date_picker.PickerView;
import com.henninghall.date_picker.R;
import org.apache.commons.lang3.LocaleUtils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -12,12 +14,13 @@ import cn.carbswang.android.numberpickerview.library.NumberPickerView;
public abstract class Wheel {
private final Wheel self;
public final int id;
public PickerView pickerView;
private String userSetValue;
abstract void init();
public abstract boolean visible();
abstract String getFormatTemplate();
public abstract String getFormatTemplate();
ArrayList<String> values;
ArrayList<String> displayValues;
@ -25,10 +28,11 @@ public abstract class Wheel {
public SimpleDateFormat format;
SimpleDateFormat displayFormat;
public Wheel(NumberPickerView picker, final PickerView pickerView) {
public Wheel(final PickerView pickerView, final int id) {
this.id = id;
this.self = this;
this.pickerView = pickerView;
this.picker = picker;
this.picker = (NumberPickerView) pickerView.findViewById(id);
refresh(false);
picker.setOnValueChangedListener(new NumberPickerView.OnValueChangeListener() {
@Override

+ 63
- 0
android/src/main/java/com/henninghall/date_picker/wheels/YearWheel.java View File

@ -0,0 +1,63 @@
package com.henninghall.date_picker.wheels;
import com.henninghall.date_picker.Mode;
import com.henninghall.date_picker.PickerView;
import java.util.Calendar;
public class YearWheel extends Wheel
{
private int defaultStartYear;
private int defaultEndYear;
public YearWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
this.defaultStartYear = 0;
this.defaultEndYear = 2100;
}
@Override
void init() {
final int startYear = getStartYear();
final int endYear = getEndYear() ;
int max = endYear - startYear;
for (int i = 0; i <= max; ++i) {
values.add(String.valueOf(startYear + i));
displayValues.add(String.valueOf(startYear + i));
}
picker.setDisplayedValues(displayValues.toArray(new String[0]));
picker.setMinValue(0);
picker.setMaxValue(max);
}
private int getEndYear() {
if (this.pickerView.maxDate == null) {
return this.defaultEndYear;
}
final Calendar cal = Calendar.getInstance();
cal.setTime(this.pickerView.maxDate);
return cal.get(Calendar.YEAR);
}
private int getStartYear() {
if (this.pickerView.minDate != null) {
final Calendar cal = Calendar.getInstance();
cal.setTime(this.pickerView.minDate);
return cal.get(Calendar.YEAR);
}
return this.defaultStartYear;
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
@Override
public String getFormatTemplate() {
return "y";
}
}

+ 42
- 0
android/src/main/res/layout/datepicker_view.xml View File

@ -16,6 +16,48 @@
android:layout_centerHorizontal="true"
android:foregroundGravity="center"
>
<cn.carbswang.android.numberpickerview.library.NumberPickerView
android:id="@+id/year"
android:layout_width="wrap_content"
android:layout_height="160dp"
app:npv_ShowCount="5"
app:npv_RespondChangeOnDetached="false"
app:npv_TextSizeNormal="18sp"
app:npv_TextSizeSelected="21sp"
app:npv_WrapSelectorWheel="true"
app:npv_TextColorSelected="#000000"
app:npv_TextColorNormal="#aaaaaa"
app:npv_DividerColor="#cccccc"
app:npv_ItemPaddingHorizontal="3dp"
/>
<cn.carbswang.android.numberpickerview.library.NumberPickerView
android:id="@+id/month"
android:layout_width="wrap_content"
android:layout_height="160dp"
app:npv_ShowCount="5"
app:npv_RespondChangeOnDetached="false"
app:npv_TextSizeNormal="18sp"
app:npv_TextSizeSelected="21sp"
app:npv_WrapSelectorWheel="true"
app:npv_TextColorSelected="#000000"
app:npv_TextColorNormal="#aaaaaa"
app:npv_DividerColor="#cccccc"
app:npv_ItemPaddingHorizontal="3dp"
/>
<cn.carbswang.android.numberpickerview.library.NumberPickerView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="160dp"
app:npv_ShowCount="5"
app:npv_RespondChangeOnDetached="false"
app:npv_TextSizeNormal="18sp"
app:npv_TextSizeSelected="21sp"
app:npv_WrapSelectorWheel="true"
app:npv_TextColorSelected="#000000"
app:npv_TextColorNormal="#aaaaaa"
app:npv_DividerColor="#cccccc"
app:npv_ItemPaddingHorizontal="3dp"
/>
<cn.carbswang.android.numberpickerview.library.NumberPickerView
android:id="@+id/day"
android:layout_width="wrap_content"

+ 2
- 1
example/android/build.gradle View File

@ -7,9 +7,10 @@ buildscript {
url 'https://maven.google.com/'
name 'Google'
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.android.tools.build:gradle:3.1.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

+ 2
- 2
example/android/gradle/wrapper/gradle-wrapper.properties View File

@ -1,6 +1,6 @@
#Thu Apr 19 20:55:10 CEST 2018
#Wed Aug 29 20:29:50 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

+ 1
- 0
example/src/exampleKeys.js View File

@ -2,4 +2,5 @@ export const EXAMPLE_KEYS = {
MINIMAL : 'MINIMAL',
ADVANCED : 'ADVANCED',
TIME_MODE : 'TIME_MODE',
DATE_MODE : 'DATE_MODE',
}

+ 5
- 0
example/src/examples.js View File

@ -3,6 +3,7 @@ import Minimal from './examples/Minimal'
import Advanced from './examples/Advanced'
import TimeMode from './examples/TimeMode'
import { EXAMPLE_KEYS } from './exampleKeys'
import DateMode from './examples/DateMode';
export default {
[EXAMPLE_KEYS.MINIMAL]: {
@ -16,5 +17,9 @@ export default {
[EXAMPLE_KEYS.TIME_MODE]: {
buttonTitle: 'Time mode',
component: TimeMode
},
[EXAMPLE_KEYS.DATE_MODE]: {
buttonTitle: 'Date mode',
component: DateMode
}
}

+ 1
- 1
example/src/examples/Advanced.js View File

@ -35,7 +35,7 @@ export default class Advanced extends Component {
locale={this.state.locale}
minuteInterval={1}
minimumDate={new Date()}
maximumDate={(new Date()).addHours(24 * 5)}
maximumDate={(new Date()).addHours(24 * 5 * 1000)}
fadeToColor={this.props.backgroundColor}
textColor={this.state.textColor}
mode={this.state.mode}

+ 17
- 0
example/src/examples/DateMode.js View File

@ -0,0 +1,17 @@
import React, { Component } from 'react';
import DatePicker from 'react-native-date-picker-x';
export default class DateMode extends Component {
state = { date: new Date() }
render = () =>
<DatePicker
date={this.state.date}
onDateChange={date => this.setState({ date })}
mode={'date'}
style={{borderWidth: 1}}
locale={'sv-SE'}
/>
}

+ 82
- 0
temp/DatePickerManager.java View File

@ -0,0 +1,82 @@
package com.henninghall.date_picker;
import android.view.*;
import com.facebook.react.uimanager.*;
import net.time4j.android.*;
import android.content.*;
import android.support.annotation.*;
import com.facebook.react.uimanager.annotations.*;
import org.apache.commons.lang3.*;
import java.util.*;
import com.facebook.react.common.*;
public class DatePickerManager extends SimpleViewManager<View>
{
public static final String REACT_CLASS = "DatePickerManager";
public static ThemedReactContext context;
public String getName() {
return "DatePickerManager";
}
public PickerView createViewInstance(final ThemedReactContext reactContext) {
ApplicationStarter.initialize((Context)(DatePickerManager.context = reactContext), true);
return new PickerView();
}
@ReactProp(name = "mode")
public void setMode(final PickerView view, @Nullable final String mode) {
try {
view.setMode(Mode.valueOf(mode));
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid mode. Valid modes: 'datetime', 'date', 'time'");
}
}
@ReactProp(name = "date")
public void setDate(final PickerView view, @Nullable final double date) {
view.setDate(Utils.unixToDate(date));
}
@ReactProp(name = "locale")
public void setLocale(final PickerView view, @Nullable final String locale) {
view.setLocale(LocaleUtils.toLocale(locale.replace('-', '_')));
view.requestLayout();
}
@ReactProp(name = "minimumDate")
public void setMinimumDate(final PickerView view, @Nullable final double date) {
view.setMinimumDate(Utils.unixToDate(date));
}
@ReactProp(name = "maximumDate")
public void setMaximumDate(final PickerView view, @Nullable final double date) {
view.setMaximumDate(Utils.unixToDate(date));
}
@ReactProp(name = "fadeToColor")
public void setFadeToColor(final PickerView view, @Nullable final String color) {
view.style.setFadeToColor(color);
}
@ReactProp(name = "textColor")
public void setTextColor(final PickerView view, @Nullable final String color) {
view.style.setTextColor(color);
}
@ReactProp(name = "minuteInterval")
public void setMinuteInterval(final PickerView view, @Nullable final int interval) throws Exception {
if (interval < 0 || interval > 59) {
throw new Exception("Minute interval out of bounds");
}
if (interval > 1) {
view.setMinuteInterval(interval);
}
}
public Map getExportedCustomBubblingEventTypeConstants() {
return MapBuilder.builder().put((Object)"dateChange", (Object)MapBuilder.of((Object)"phasedRegistrationNames", (Object)MapBuilder.of((Object)"bubbled", (Object)"onChange"))).build();
}
}

+ 38
- 0
temp/DateWheel.java View File

@ -0,0 +1,38 @@
-ckage com.henninghall.date_picker.wheels;
import java.util.*;
import com.henninghall.date_picker.*;
public class DateWheel extends Wheel
{
public DateWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
}
@Override
void init() {
final int maxDate = 31;
final int minDate = 1;
final Calendar cal = this.pickerView.getInitialDate();
final String initialDate = this.format.format(cal.getTime());
for (int i = minDate; i <= maxDate; ++i) {
final int currentDate = (Integer.valueOf(initialDate) + i) % maxDate + 1;
final String currentDateString = String.valueOf(currentDate);
this.values.add(currentDateString);
this.displayValues.add(currentDateString);
}
this.picker.setDisplayedValues((String[])this.displayValues.toArray(new String[0]));
this.picker.setMinValue(0);
this.picker.setMaxValue(maxDate - minDate);
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
public String getFormatTemplate() {
return "d";
}
}

+ 9
- 0
temp/Mode.java View File

@ -0,0 +1,9 @@
package com.henninghall.date_picker;
public enum Mode
{
date,
time,
datetime;
}

+ 38
- 0
temp/MonthWheel.java View File

@ -0,0 +1,38 @@
package com.henninghall.date_picker.wheels;
import java.text.*;
import java.util.*;
import com.henninghall.date_picker.*;
public class MonthWheel extends Wheel
{
public MonthWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
}
@Override
void init() {
final int min = 0;
final int max = 12;
final Calendar cal = this.pickerView.getInitialDate();
final SimpleDateFormat format = new SimpleDateFormat(this.getFormatTemplate(), this.pickerView.locale);
for (int i = min; i <= max; ++i) {
this.values.add(format.format(cal.getTime()));
this.displayValues.add(format.format(cal.getTime()));
cal.add(2, 1);
}
this.picker.setDisplayedValues((String[])this.displayValues.toArray(new String[0]));
this.picker.setMinValue(0);
this.picker.setMaxValue(max);
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
public String getFormatTemplate() {
return "LLLL";
}
}

+ 184
- 0
temp/PickerView.java View File

@ -0,0 +1,184 @@
package com.henninghall.date_picker;
import android.widget.*;
import cn.carbswang.android.numberpickerview.library.*;
import android.content.*;
import com.henninghall.date_picker.wheels.*;
import com.facebook.react.uimanager.events.*;
import java.text.*;
import com.facebook.react.bridge.*;
import android.view.*;
import android.os.*;
import org.apache.commons.lang3.time.*;
import com.henninghall.date_picker.wheelFunctions.*;
import java.util.*;
public class PickerView extends RelativeLayout
{
private final NumberPickerView hourPicker;
private final NumberPickerView ampmPicker;
private SimpleDateFormat dateFormat;
private HourWheel hourWheel;
private DayWheel dayWheel;
public MinutesWheel minutesWheel;
private AmPmWheel ampmWheel;
private Date minDate;
private Date maxDate;
public int minuteInterval;
public Locale locale;
public Mode mode;
public Style style;
WheelChangeListener onWheelChangeListener;
private final Runnable measureAndLayout;
public PickerView() {
super((Context)DatePickerManager.context);
this.minuteInterval = 1;
this.onWheelChangeListener = new WheelChangeListener() {
@Override
public void onChange(final Wheel wheel) {
final WritableMap event = Arguments.createMap();
try {
final Date date = PickerView.this.dateFormat.parse(PickerView.this.getDateString());
if (PickerView.this.minDate != null && date.before(PickerView.this.minDate)) {
PickerView.this.applyOnVisibleWheels(new AnimateToDate(PickerView.this.minDate));
}
else if (PickerView.this.maxDate != null && date.after(PickerView.this.maxDate)) {
PickerView.this.applyOnVisibleWheels(new AnimateToDate(PickerView.this.maxDate));
}
else {
event.putDouble("date", (double)date.getTime());
((RCTEventEmitter)DatePickerManager.context.getJSModule((Class)RCTEventEmitter.class)).receiveEvent(PickerView.this.getId(), "dateChange", event);
}
}
catch (ParseException e) {
e.printStackTrace();
}
}
};
this.measureAndLayout = new Runnable() {
@Override
public void run() {
PickerView.this.measure(View.MeasureSpec.makeMeasureSpec(PickerView.this.getWidth(), 1073741824), View.MeasureSpec.makeMeasureSpec(PickerView.this.getHeight(), 1073741824));
PickerView.this.layout(PickerView.this.getLeft(), PickerView.this.getTop(), PickerView.this.getRight(), PickerView.this.getBottom());
}
};
final View rootView = inflate(this.getContext(), R.layout.datepicker_view, (ViewGroup)this);
this.style = new Style(this);
final RelativeLayout wheelsWrapper = (RelativeLayout)rootView.findViewById(R.id.wheelsWrapper);
wheelsWrapper.setWillNotDraw(false);
this.locale = ((Build.VERSION.SDK_INT >= 21) ? Locale.forLanguageTag("en") : Locale.getDefault());
final NumberPickerView dayPicker = (NumberPickerView)rootView.findViewById(R.id.day);
this.dayWheel = new DayWheel(dayPicker, this);
final NumberPickerView minutePicker = (NumberPickerView)rootView.findViewById(R.id.minutes);
this.minutesWheel = new MinutesWheel(minutePicker, this);
this.ampmPicker = (NumberPickerView)rootView.findViewById(R.id.ampm);
this.ampmWheel = new AmPmWheel(this.ampmPicker, this);
this.hourPicker = (NumberPickerView)rootView.findViewById(R.id.hour);
this.hourWheel = new HourWheel(this.hourPicker, this);
this.dateFormat = new SimpleDateFormat(this.getDateFormatTemplate(), Locale.US);
this.changeAmPmWhenPassingMidnightOrNoon();
}
private void changeAmPmWhenPassingMidnightOrNoon() {
this.hourPicker.setOnValueChangeListenerInScrolling((NumberPickerView.OnValueChangeListenerInScrolling)new NumberPickerView.OnValueChangeListenerInScrolling() {
public void onValueChangeInScrolling(final NumberPickerView picker, final int oldVal, final int newVal) {
if (Utils.usesAmPm(PickerView.this.locale)) {
final String oldValue = PickerView.this.hourWheel.getValueAtIndex(oldVal);
final String newValue = PickerView.this.hourWheel.getValueAtIndex(newVal);
final boolean passingNoonOrMidnight = (oldValue.equals("12") && newValue.equals("11")) || (oldValue.equals("11") && newValue.equals("12"));
if (passingNoonOrMidnight) {
PickerView.this.ampmPicker.smoothScrollToValue((PickerView.this.ampmPicker.getValue() + 1) % 2, false);
}
}
}
});
}
public void setMinimumDate(final Date date) {
this.minDate = DateUtils.truncate(date, 12);
}
public void setMaximumDate(final Date date) {
this.maxDate = DateUtils.truncate(date, 12);
}
public void setDate(final Date date) {
this.applyOnAllWheels(new SetDate(date));
}
public void setLocale(final Locale locale) {
this.locale = locale;
this.dateFormat = new SimpleDateFormat(this.getDateFormatTemplate(), Locale.US);
this.applyOnAllWheels(new Refresh());
}
public void setMinuteInterval(final int interval) {
this.minuteInterval = interval;
this.applyOnVisibleWheels(new Refresh());
}
public Calendar getInitialDate() {
final Calendar cal = Calendar.getInstance();
if (this.minuteInterval <= 1) {
return cal;
}
final int exactMinute = Integer.valueOf(this.minutesWheel.format.format(cal.getTime()));
final int diffSinceLastInterval = exactMinute % this.minuteInterval;
final int diffAhead = this.minuteInterval - diffSinceLastInterval;
final int diffBehind = -diffSinceLastInterval;
final boolean closerToPrevious = this.minuteInterval / 2 > diffSinceLastInterval;
final int diffToExactValue = closerToPrevious ? diffBehind : diffAhead;
cal.add(12, diffToExactValue);
return (Calendar)cal.clone();
}
private String getDateFormatTemplate() {
return this.dayWheel.getFormatTemplate() + " " + this.hourWheel.getFormatTemplate() + " " + this.minutesWheel.getFormatTemplate() + this.ampmWheel.getFormatTemplate();
}
private String getDateString() {
return this.dayWheel.getValue() + " " + this.hourWheel.getValue() + " " + this.minutesWheel.getValue() + this.ampmWheel.getValue();
}
public void setMode(final Mode mode) {
this.mode = mode;
this.applyOnAllWheels(new Refresh());
}
public Collection<Wheel> getVisibleWheels() {
final Collection<Wheel> visibleWheels = new ArrayList<Wheel>();
for (final Wheel wheel : this.getAllWheels()) {
if (wheel.visible()) {
visibleWheels.add(wheel);
}
}
return visibleWheels;
}
public List<Wheel> getAllWheels() {
return new ArrayList<Wheel>(Arrays.asList(this.dayWheel, this.hourWheel, this.minutesWheel, this.ampmWheel));
}
public void applyOnAllWheels(final WheelFunction function) {
for (final Wheel wheel : this.getAllWheels()) {
function.apply(wheel);
}
}
public void applyOnVisibleWheels(final WheelFunction function) {
for (final Wheel wheel : this.getVisibleWheels()) {
function.apply(wheel);
}
}
public void requestLayout() {
super.requestLayout();
this.post(this.measureAndLayout);
}
public WheelChangeListener getListener() {
return this.onWheelChangeListener;
}
}

+ 100
- 0
temp/Wheel.java View File

@ -0,0 +1,100 @@
package com.henninghall.date_picker.wheels;
import com.henninghall.date_picker.*;
import cn.carbswang.android.numberpickerview.library.*;
import java.text.*;
import java.util.*;
import org.apache.commons.lang3.*;
public abstract class Wheel
{
private final Wheel self;
public PickerView pickerView;
private String userSetValue;
ArrayList<String> values;
ArrayList<String> displayValues;
public NumberPickerView picker;
public SimpleDateFormat format;
SimpleDateFormat displayFormat;
abstract void init();
public abstract boolean visible();
abstract String getFormatTemplate();
public Wheel(final NumberPickerView picker, final PickerView pickerView) {
this.self = this;
this.pickerView = pickerView;
this.picker = picker;
this.refresh(false);
picker.setOnValueChangedListener((NumberPickerView.OnValueChangeListener)new NumberPickerView.OnValueChangeListener() {
public void onValueChange(final NumberPickerView picker, final int oldVal, final int newVal) {
pickerView.getListener().onChange(Wheel.this.self);
}
});
}
public int getIndexOfDate(final Date date) {
return this.values.indexOf(this.format.format(date));
}
public void animateToDate(final Date date) {
this.picker.smoothScrollToValue(this.getIndexOfDate(date));
}
public String getValue() {
if (!this.visible()) {
return this.userSetValue;
}
return this.getValueAtIndex(this.getIndex());
}
public int getIndex() {
return this.picker.getValue();
}
public String getValueAtIndex(final int index) {
return this.values.get(index);
}
public void setValue(final Date date) {
this.userSetValue = this.format.format(date);
final int index = this.getIndexOfDate(date);
if (index > -1) {
if (this.picker.getValue() == 0) {
this.picker.setValue(index);
}
else {
this.picker.smoothScrollToValue(index);
}
}
}
public void refresh(final boolean keepOldValue) {
this.displayFormat = new SimpleDateFormat(this.getFormatTemplate(), this.pickerView.locale);
this.format = new SimpleDateFormat(this.getFormatTemplate(), LocaleUtils.toLocale("en_US"));
this.values = new ArrayList<String>();
this.displayValues = new ArrayList<String>();
final int oldValue = this.picker.getValue();
if (this.visible()) {
this.add();
this.init();
if (keepOldValue) {
this.picker.setValue(oldValue);
}
}
else {
this.remove();
}
}
private void remove() {
this.picker.setVisibility(8);
}
private void add() {
this.picker.setVisibility(0);
}
}

+ 56
- 0
temp/WheelOrderUpdater.java View File

@ -0,0 +1,56 @@
package com.henninghall.date_picker;
import com.henninghall.date_picker.wheels.*;
import java.util.*;
import android.widget.*;
import android.os.*;
import android.view.*;
public class WheelOrderUpdater
{
private final PickerView pickerView;
WheelOrderUpdater(final PickerView v) {
this.pickerView = v;
}
public void update(final Locale locale, final Mode mode) {
if (mode != Mode.date) {
return;
}
final String ymdPattern = Utils.localeToYmdPattern(locale);
final ArrayList<Wheel> wheelOrder = this.ymdPatternToWheelOrder(ymdPattern);
this.placeWheelRightOf(wheelOrder.get(0), wheelOrder.get(1));
this.placeWheelRightOf(wheelOrder.get(1), wheelOrder.get(2));
}
private void placeWheelRightOf(final Wheel leftWheel, final Wheel rightWheel) {
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, Utils.getWheelHeight((View)this.pickerView));
params.addRule(1, leftWheel.id);
if (Build.VERSION.SDK_INT >= 17) {
params.addRule(17, leftWheel.id);
}
rightWheel.picker.setLayoutParams((ViewGroup.LayoutParams)params);
}
private ArrayList<Wheel> ymdPatternToWheelOrder(final String ymdPattern) {
final String[] parts = ymdPattern.split("/");
final ArrayList<Wheel> wheelList = new ArrayList<Wheel>();
for (final String s : parts) {
switch (s.charAt(0)) {
case 'y': {
wheelList.add(this.pickerView.yearWheel);
}
case 'M': {
wheelList.add(this.pickerView.monthWheel);
}
case 'd': {
wheelList.add(this.pickerView.dateWheel);
break;
}
}
}
return wheelList;
}
}

+ 58
- 0
temp/YearWheel.java View File

@ -0,0 +1,58 @@
package com.henninghall.date_picker.wheels;
import java.util.*;
import com.henninghall.date_picker.*;
public class YearWheel extends Wheel
{
private int defaultStartYear;
private int defaultEndYear;
public YearWheel(final PickerView pickerView, final int id) {
super(pickerView, id);
this.defaultStartYear = 0;
this.defaultEndYear = 2100;
}
@Override
void init() {
final int startYear = this.getStartYear();
final int endYear = this.getEndYear();
for (int i = startYear; i <= endYear; ++i) {
this.values.add(String.valueOf(i));
this.displayValues.add(String.valueOf(i));
}
this.picker.setDisplayedValues((String[])this.displayValues.toArray(new String[0]));
final int year = Calendar.getInstance().get(1);
this.picker.setMinValue(startYear);
this.picker.setMaxValue(endYear);
}
private int getEndYear() {
if (this.pickerView.maxDate == null) {
return this.defaultEndYear;
}
final Calendar cal = Calendar.getInstance();
cal.setTime(this.pickerView.maxDate);
return cal.get(1);
}
private int getStartYear() {
if (this.pickerView.minDate != null) {
final Calendar cal = Calendar.getInstance();
cal.setTime(this.pickerView.minDate);
return cal.get(1);
}
return this.defaultStartYear;
}
@Override
public boolean visible() {
return this.pickerView.mode == Mode.date;
}
public String getFormatTemplate() {
return "y";
}
}

Loading…
Cancel
Save