diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..9121ffa7
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+ko_fi: FlorentChampigny
+github: florent37
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 1c9422fe..cded514b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,5 @@ freeline/
freeline_project_description.json
SingleDateAndTimePicker.iml
app/app.iml
+# OS specific (mac)
+.DS_Store
diff --git a/README.md b/README.md
index 94cd470e..5520c1bb 100644
--- a/README.md
+++ b/README.md
@@ -17,20 +17,21 @@ You can now select a date and a time with only one widget !
new SingleDateAndTimePickerDialog.Builder(context)
//.bottomSheet()
//.curved()
- //.minutesStep(15)
-
+ //.stepSizeMinutes(15)
//.displayHours(false)
//.displayMinutes(false)
-
//.todayText("aujourd'hui")
-
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
- @Override
- public void onDisplayed(SingleDateAndTimePicker picker) {
- //retrieve the SingleDateAndTimePicker
- }
- })
-
+ @Override
+ public void onDisplayed(SingleDateAndTimePicker picker) {
+ // Retrieve the SingleDateAndTimePicker
+ }
+
+ @Override
+ public void onClosed(SingleDateAndTimePicker picker) {
+ // On dialog closed
+ }
+ })
.title("Simple")
.listener(new SingleDateAndTimePickerDialog.Listener() {
@Override
@@ -48,7 +49,7 @@ new SingleDateAndTimePickerDialog.Builder(context)
new DoubleDateAndTimePickerDialog.Builder(context)
//.bottomSheet()
//.curved()
- //.minutesStep(15)
+ //.stepSizeMinutes(15)
.title("Double")
.tab0Text("Depart")
.tab1Text("Return")
@@ -66,7 +67,6 @@ new DoubleDateAndTimePickerDialog.Builder(context)
```java
new SingleDateAndTimePickerDialog.Builder(this)
-
.bottomSheet()
.curved()
.displayMinutes(false)
@@ -88,7 +88,6 @@ new SingleDateAndTimePickerDialog.Builder(this)
android:layout_height="230dp"
app:picker_curved="true"
app:picker_cyclic="true"
- app:picker_canBeOnPast="false"
app:picker_visibleItemCount="7"
/>
```
@@ -116,9 +115,7 @@ new DoubleDateAndTimePickerDialog.Builder(context)
You can change the minutes steps (default : 5min)
```java
new SingleDateAndTimePickerDialog.Builder(context)
-
- .minutesStep(15)
-
+ .stepSizeMinutes(15)
.display();
```
@@ -128,53 +125,99 @@ And change some colors
```java
new SingleDateAndTimePickerDialog.Builder(context)
-
.backgroundColor(Color.BLACK)
.mainColor(Color.GREEN)
.titleColor(Color.WHITE)
-
.display();
```
# Date range
-Force user to select a date between a range
+Require user to select a date between a range
```java
new SingleDateAndTimePickerDialog.Builder(context)
-
.defaultDate(defaultDate)
.minDateRange(minDate)
.maxDateRange(maxDate)
-
.display();
```
-Or simply force user to select a future date
+Or simply require user to select a future date
```java
new SingleDateAndTimePickerDialog.Builder(context)
-
.mustBeOnFuture()
-
.display();
```
+# Changing typeface
+
+```java
+final SingleDateAndTimePicker singleDateAndTimePicker2 = findViewById(R.id.single_day_picker2);
+singleDateAndTimePicker2.setTypeface(ResourcesCompat.getFont(this, R.font.dinot_regular));
+```
+
+Or pass it as an attribute in the XML layout. (See XML section on how to use it.)
+
+# XML
+
+Some/most options are also available via XML:
+
+```
+
+```
+
+* picker_itemSpacing: Margin between items. Only has effect with
+ height=wrap-content
+* picker_curvedMaxAngle sets the max angle of top/bottom items. If 45
+ then the visible 'window' of the wheel is a 'quarter' of the circle.
+ If 90 (default) its rolling on a half-circle
+* `app:fontFamily` or `android:fontFamily` sets the typeface/font to be
+ used with the date picker.
+ Note - For api below v-16 use `app:fontFamily`
+
+Get divider lines around selected by overwriting one or more of
+```
+ @android:color/transparent
+ 1dp
+ @drawable/picker_divider
+```
+Use in conjuction with
+`app:picker_selectorColor="@android:color/transparent"` on layout.
+
# Download
In your module [![Download](https://api.bintray.com/packages/florent37/maven/SingleDateAndTimePicker/images/download.svg)](https://bintray.com/florent37/maven/SingleDateAndTimePicker/_latestVersion)
```groovy
-compile 'com.github.florent37:singledateandtimepicker:(last version)'
+implementation 'com.github.florent37:singledateandtimepicker:2.2.7'
+//compatible with androidX
```
# Credits
-Author: Florent Champigny [http://www.florentchampigny.com/](http://www.florentchampigny.com/)
+Author: Florent Champigny
Blog : [http://www.tutos-android-france.com/](http://www.tutos-android-france.com/)
+Fiches Plateau Moto : [https://www.fiches-plateau-moto.fr/](https://www.fiches-plateau-moto.fr/)
diff --git a/app/build.gradle b/app/build.gradle
index 4dacfe62..afec38dd 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -14,7 +14,11 @@ android {
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
}
-
+ // The demo-app uses butterknife which require java8
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
android {
lintOptions {
abortOnError false
@@ -24,9 +28,9 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'com.android.support:appcompat-v7:' + project.supportVersion
- implementation 'com.android.support:design:' + project.supportVersion
- implementation 'com.jakewharton:butterknife:8.8.1'
- annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
+ implementation "androidx.appcompat:appcompat:1.1.0"
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'com.jakewharton:butterknife:10.2.1'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
implementation project(':singledateandtimepicker')
}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivity.java b/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivity.java
index 776c8edc..fa7e9dfe 100644
--- a/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivity.java
+++ b/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivity.java
@@ -1,11 +1,12 @@
package com.github.florent37.sample.singledateandtimepicker;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.content.res.ResourcesCompat;
+
import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
-import java.util.Date;
public class SingleDatePickerMainActivity extends AppCompatActivity {
@@ -14,19 +15,22 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_date_picker_activity_main);
- final SingleDateAndTimePicker singleDateAndTimePicker = (SingleDateAndTimePicker) findViewById(R.id.single_day_picker);
- singleDateAndTimePicker.addOnDateChangedListener(new SingleDateAndTimePicker.OnDateChangedListener() {
- @Override
- public void onDateChanged(String displayed, Date date) {
- display(displayed);
- }
- });
+ final SingleDateAndTimePicker singleDateAndTimePicker = findViewById(R.id.single_day_picker);
+ final SingleDateAndTimePicker singleDateAndTimePicker2 = findViewById(R.id.single_day_picker2);
+ // Example for setting default selected date to yesterday
+// Calendar instance = Calendar.getInstance();
+// instance.add(Calendar.DATE, -1 );
+// singleDateAndTimePicker.setDefaultDate(instance.getTime());
+ SingleDateAndTimePicker.OnDateChangedListener changeListener = (displayed, date) -> display(displayed);
+ singleDateAndTimePicker.addOnDateChangedListener(changeListener);
+ singleDateAndTimePicker2.addOnDateChangedListener(changeListener);
+
+ //singleDateAndTimePicker.setTypeface(Typeface.DEFAULT);
+ singleDateAndTimePicker2.setTypeface(ResourcesCompat.getFont(this, R.font.dinot_regular));
- findViewById(R.id.toggleEnabled).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- singleDateAndTimePicker.setEnabled(!singleDateAndTimePicker.isEnabled());
- }
+ findViewById(R.id.toggleEnabled).setOnClickListener(v -> {
+ singleDateAndTimePicker.setEnabled(!singleDateAndTimePicker.isEnabled());
+ singleDateAndTimePicker2.setEnabled(!singleDateAndTimePicker2.isEnabled());
});
}
diff --git a/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivityWithDoublePicker.java b/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivityWithDoublePicker.java
index 496eaa5b..c6846449 100644
--- a/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivityWithDoublePicker.java
+++ b/app/src/main/java/com/github/florent37/sample/singledateandtimepicker/SingleDatePickerMainActivityWithDoublePicker.java
@@ -1,9 +1,9 @@
package com.github.florent37.sample.singledateandtimepicker;
-import android.graphics.Color;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
import android.widget.TextView;
+import android.widget.Toast;
import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
import com.github.florent37.singledateandtimepicker.dialog.DoubleDateAndTimePickerDialog;
@@ -14,8 +14,10 @@
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
+import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
@@ -24,6 +26,7 @@ public class SingleDatePickerMainActivityWithDoublePicker extends AppCompatActiv
@BindView(R.id.doubleText)
TextView doubleText;
+
@BindView(R.id.singleText)
TextView singleText;
@@ -33,14 +36,19 @@ public class SingleDatePickerMainActivityWithDoublePicker extends AppCompatActiv
@BindView(R.id.singleDateText)
TextView singleDateText;
+ @BindView(R.id.singleDateLocaleText)
+ TextView singleDateLocaleText;
SimpleDateFormat simpleDateFormat;
SimpleDateFormat simpleTimeFormat;
SimpleDateFormat simpleDateOnlyFormat;
+ SimpleDateFormat simpleDateLocaleFormat;
SingleDateAndTimePickerDialog.Builder singleBuilder;
DoubleDateAndTimePickerDialog.Builder doubleBuilder;
+ private static String TAG = "SingleDatePickerMainActivityWithDoublePicker";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -52,6 +60,8 @@ protected void onCreate(Bundle savedInstanceState) {
this.simpleTimeFormat = new SimpleDateFormat("hh:mm aa", Locale.getDefault());
this.simpleDateOnlyFormat = new SimpleDateFormat("EEE d MMM", Locale.getDefault());
+
+ this.simpleDateLocaleFormat = new SimpleDateFormat("EEE d MMM", Locale.GERMAN);
}
@Override
@@ -76,7 +86,7 @@ public void simpleTimeClicked() {
final Date defaultDate = calendar.getTime();
singleBuilder = new SingleDateAndTimePickerDialog.Builder(this)
-
+ .setTimeZone(TimeZone.getDefault())
.bottomSheet()
.curved()
@@ -88,14 +98,19 @@ public void simpleTimeClicked() {
.displayMinutes(true)
.displayHours(true)
- .displayDays(true)
+ .displayDays(false)
//.displayMonth(true)
//.displayYears(true)
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
@Override
public void onDisplayed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog displayed");
+ }
+ @Override
+ public void onClosed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog closed");
}
})
@@ -117,7 +132,7 @@ public void simpleDateClicked() {
final Date defaultDate = calendar.getTime();
singleBuilder = new SingleDateAndTimePickerDialog.Builder(this)
-
+ .setTimeZone(TimeZone.getDefault())
.bottomSheet()
.curved()
@@ -132,7 +147,12 @@ public void simpleDateClicked() {
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
@Override
public void onDisplayed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog displayed");
+ }
+ @Override
+ public void onClosed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog closed");
}
})
@@ -159,6 +179,7 @@ public void simpleClicked() {
final Date defaultDate = calendar.getTime();
singleBuilder = new SingleDateAndTimePickerDialog.Builder(this)
+ .setTimeZone(TimeZone.getDefault())
.bottomSheet()
.curved()
@@ -185,7 +206,12 @@ public void simpleClicked() {
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
@Override
public void onDisplayed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog displayed");
+ }
+ @Override
+ public void onClosed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog closed");
}
})
@@ -213,6 +239,7 @@ public void doubleClicked() {
final Date maxDate = calendarMax.getTime();
doubleBuilder = new DoubleDateAndTimePickerDialog.Builder(this)
+ .setTimeZone(TimeZone.getDefault())
//.bottomSheet()
//.curved()
@@ -246,4 +273,36 @@ public void onDateSelected(List dates) {
});
doubleBuilder.display();
}
+
+ @OnClick(R.id.singleDateLocaleLayout)
+ public void singleDateLocaleClicked() {
+ singleBuilder = new SingleDateAndTimePickerDialog.Builder(this)
+ .customLocale(Locale.GERMAN)
+ .bottomSheet()
+ .curved()
+ .displayHours(false)
+ .displayMinutes(false)
+ .displayDays(true)
+
+ .displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
+ @Override
+ public void onDisplayed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog displayed");
+ }
+
+ @Override
+ public void onClosed(SingleDateAndTimePicker picker) {
+ Log.d(TAG, "Dialog closed");
+ }
+ })
+
+ .title("")
+ .listener(new SingleDateAndTimePickerDialog.Listener() {
+ @Override
+ public void onDateSelected(Date date) {
+ singleDateLocaleText.setText(simpleDateLocaleFormat.format(date));
+ }
+ });
+ singleBuilder.display();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/font/dinot_bold.ttf b/app/src/main/res/font/dinot_bold.ttf
new file mode 100644
index 00000000..25b996c5
Binary files /dev/null and b/app/src/main/res/font/dinot_bold.ttf differ
diff --git a/app/src/main/res/font/dinot_regular.ttf b/app/src/main/res/font/dinot_regular.ttf
new file mode 100644
index 00000000..c379f2fb
Binary files /dev/null and b/app/src/main/res/font/dinot_regular.ttf differ
diff --git a/app/src/main/res/layout/single_date_picker_activity_main.xml b/app/src/main/res/layout/single_date_picker_activity_main.xml
index e357689e..bb618c4f 100644
--- a/app/src/main/res/layout/single_date_picker_activity_main.xml
+++ b/app/src/main/res/layout/single_date_picker_activity_main.xml
@@ -1,28 +1,65 @@
+ android:orientation="vertical">
+ android:layout_marginBottom="50dp"
+ android:text="toggle enabled" />
+
+
+
+
+ app:picker_selectorColor="@android:color/transparent"
+ app:picker_textAlign="center"
+ app:picker_visibleItemCount="9"
+ app:fontFamily="@font/dinot_bold"/>
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/single_date_picker_activity_main_double_picker.xml b/app/src/main/res/layout/single_date_picker_activity_main_double_picker.xml
index ae2f221e..17cb48cd 100644
--- a/app/src/main/res/layout/single_date_picker_activity_main_double_picker.xml
+++ b/app/src/main/res/layout/single_date_picker_activity_main_double_picker.xml
@@ -6,7 +6,7 @@
android:orientation="vertical"
>
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 7d09ae14..311d603b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -6,4 +6,7 @@
#AAA
#6E6E6E
+
+ #E3E3E3
+
diff --git a/build.gradle b/build.gradle
index ec72c114..ba2ea3fd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,9 +6,9 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.2'
- classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
- classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0'
+ classpath 'com.android.tools.build:gradle:3.6.2'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -23,14 +23,13 @@ allprojects {
}
ext {
- sdk = 27
+ sdk = 28
minSdk = 14
- supportVersion = "27.0.2"
github = 'https://github.com/florent37/SingleDateAndTimePicker'
libraryGroup = 'com.github.florent37'
libraryName = 'singledateandtimepicker'
- libraryVersion = "2.0.5"
+ libraryVersion = "2.2.8"
libraryDescription = 'SingleDateAndTimePicker'
}
diff --git a/gradle.properties b/gradle.properties
index f1c49f39..1e0c1d3b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,6 +9,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
+android.enableJetifier=true
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 2a901c63..a47afbd2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Apr 09 13:56:13 CEST 2018
+#Thu Apr 02 15:16:52 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/publish.sh b/publish.sh
index bdfb5763..cd299203 100755
--- a/publish.sh
+++ b/publish.sh
@@ -1,2 +1,4 @@
-./gradlew clean assembleDebug
-./gradlew install bintrayUpload
\ No newline at end of file
+#!/usr/bin/env bash
+. ~/.bash_profile
+./gradlew clean :singledateandtimepicker:assembleDebug
+./gradlew :singledateandtimepicker:install :singledateandtimepicker:bintrayUpload
\ No newline at end of file
diff --git a/singledateandtimepicker/build.gradle b/singledateandtimepicker/build.gradle
index 08d1a0ee..a19bbffe 100644
--- a/singledateandtimepicker/build.gradle
+++ b/singledateandtimepicker/build.gradle
@@ -6,8 +6,8 @@ android {
defaultConfig {
minSdkVersion project.minSdk
targetSdkVersion project.sdk
- versionCode 1
- versionName "1.0"
+ versionCode 2
+ versionName "1.1"
}
lintOptions {
abortOnError false
@@ -15,8 +15,7 @@ android {
}
dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.android.support:appcompat-v7:' + project.supportVersion
+ implementation "androidx.appcompat:appcompat:1.1.0"
}
ext {
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/DateHelper.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/DateHelper.java
index dc0ec1d3..b37accb7 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/DateHelper.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/DateHelper.java
@@ -1,47 +1,90 @@
package com.github.florent37.singledateandtimepicker;
+import androidx.annotation.NonNull;
+
import java.util.Calendar;
import java.util.Date;
-import java.util.Locale;
+import java.util.TimeZone;
public class DateHelper {
- public static Calendar getCalendarOfDate(Date date){
- final Calendar calendar = Calendar.getInstance(Locale.getDefault());
+ // Don't use static, as timezone may change while app is alive
+ private TimeZone timeZone = TimeZone.getDefault();
+
+ public DateHelper() {
+ this.timeZone = TimeZone.getDefault();
+ }
+
+ public DateHelper(TimeZone timeZone) {
+ this.timeZone = timeZone;
+ }
+
+ public void setTimeZone(TimeZone timeZoneValue) {
+ timeZone = timeZoneValue;
+ }
+
+ @NonNull
+ public TimeZone getTimeZone() {
+ if(this.timeZone == null) {
+ return TimeZone.getDefault();
+ } else {
+ return timeZone;
+ }
+ }
+
+ public Calendar getCalendarOfDate(Date date) {
+ final Calendar calendar = Calendar.getInstance(getTimeZone());
calendar.setTime(date);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
return calendar;
}
- public static int getHour(Date date){
+ public int getHour(Date date) {
return getCalendarOfDate(date).get(Calendar.HOUR);
}
- public static int getHourOfDay(Date date){
+ public int getHourOfDay(Date date) {
return getCalendarOfDate(date).get(Calendar.HOUR);
}
- public static int getHour(Date date, boolean isAmPm){
- if(isAmPm){
+ public int getHour(Date date, boolean isAmPm) {
+ if (isAmPm) {
return getHourOfDay(date);
} else {
return getHour(date);
}
}
- public static int getMinuteOf(Date date) {
+ public int getMinuteOf(Date date) {
return getCalendarOfDate(date).get(Calendar.MINUTE);
}
- public static Date today() {
- return Calendar.getInstance(Locale.getDefault()).getTime();
+ public Date today() {
+ Calendar now = Calendar.getInstance(getTimeZone());
+ return now.getTime();
}
- public static int getMonth(Date date) {
+ public int getMonth(Date date) {
return getCalendarOfDate(date).get(Calendar.MONTH);
}
- public static int getDay(Date date){
+ public int getDay(Date date) {
return getCalendarOfDate(date).get(Calendar.DAY_OF_MONTH);
}
+
+ public static int compareDateIgnoreTime(Date first, Date second) {
+ Date firstZeroTime = getZeroTimeDateWithoutTimeZone(first);
+ Date secondZeroTime = getZeroTimeDateWithoutTimeZone(second);
+ return firstZeroTime.compareTo(secondZeroTime);
+ }
+
+ private static Date getZeroTimeDateWithoutTimeZone(Date date) {
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar.getTime();
+ }
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/LocaleHelper.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/LocaleHelper.java
new file mode 100644
index 00000000..b96f277e
--- /dev/null
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/LocaleHelper.java
@@ -0,0 +1,47 @@
+package com.github.florent37.singledateandtimepicker;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Build;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
+import java.util.Locale;
+
+/**
+ * Helper class, provides {@link Locale} specific methods.
+ */
+public class LocaleHelper {
+
+ /**
+ * Retrieves the string from resources by specific {@link Locale}.
+ *
+ * @param context The context.
+ * @param locale The requested locale.
+ * @param resourceId The string resource id.
+ *
+ * @return The string.
+ */
+ public static String getString(@NonNull Context context, @NonNull Locale locale, @StringRes int resourceId) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ Configuration config = new Configuration(context.getResources().getConfiguration());
+ config.setLocale(locale);
+ return context.createConfigurationContext(config).getString(resourceId);
+ } else {
+ Resources resources = context.getResources();
+ Configuration conf = resources.getConfiguration();
+ Locale savedLocale = conf.locale;
+ conf.locale = locale;
+ resources.updateConfiguration(conf, null);
+
+ // retrieve resources from desired locale
+ String result = resources.getString(resourceId);
+
+ // restore original locale
+ conf.locale = savedLocale;
+ resources.updateConfiguration(conf, null);
+ return result;
+ }
+ }
+}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/SingleDateAndTimePicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/SingleDateAndTimePicker.java
index 1a21240c..baf26241 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/SingleDateAndTimePicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/SingleDateAndTimePicker.java
@@ -3,15 +3,20 @@
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
+import android.graphics.Typeface;
+import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.res.ResourcesCompat;
+
+import com.github.florent37.singledateandtimepicker.widget.DateWithLabel;
import com.github.florent37.singledateandtimepicker.widget.WheelAmPmPicker;
import com.github.florent37.singledateandtimepicker.widget.WheelDayOfMonthPicker;
import com.github.florent37.singledateandtimepicker.widget.WheelDayPicker;
@@ -27,22 +32,28 @@
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.DAYS_PADDING;
-import static com.github.florent37.singledateandtimepicker.DateHelper.getCalendarOfDate;
public class SingleDateAndTimePicker extends LinearLayout {
public static final boolean IS_CYCLIC_DEFAULT = true;
public static final boolean IS_CURVED_DEFAULT = false;
- public static final boolean MUST_BE_ON_FUTUR_DEFAULT = false;
+ public static final boolean MUST_BE_ON_FUTURE_DEFAULT = false;
public static final int DELAY_BEFORE_CHECK_PAST = 200;
private static final int VISIBLE_ITEM_COUNT_DEFAULT = 7;
private static final int PM_HOUR_ADDITION = 12;
+ public static final int ALIGN_CENTER = 0;
+ public static final int ALIGN_LEFT = 1;
+ public static final int ALIGN_RIGHT = 2;
+ private DateHelper dateHelper = new DateHelper();
private static final CharSequence FORMAT_24_HOUR = "EEE d MMM H:mm";
private static final CharSequence FORMAT_12_HOUR = "EEE d MMM h:mm a";
-
@NonNull
private final WheelYearPicker yearsPicker;
@@ -83,7 +94,6 @@ public class SingleDateAndTimePicker extends LinearLayout {
private boolean displayHours = true;
private boolean isAmPm;
- private int selectorHeight;
public SingleDateAndTimePicker(Context context) {
this(context, null);
@@ -99,15 +109,15 @@ public SingleDateAndTimePicker(Context context, AttributeSet attrs, int defStyle
defaultDate = new Date();
isAmPm = !(DateFormat.is24HourFormat(context));
- inflate(context, R.layout.single_day_picker, this);
+ inflate(context, R.layout.single_day_and_time_picker, this);
- yearsPicker = (WheelYearPicker) findViewById(R.id.yearPicker);
- monthPicker = (WheelMonthPicker) findViewById(R.id.monthPicker);
- daysOfMonthPicker = (WheelDayOfMonthPicker) findViewById(R.id.daysOfMonthPicker);
- daysPicker = (WheelDayPicker) findViewById(R.id.daysPicker);
- minutesPicker = (WheelMinutePicker) findViewById(R.id.minutesPicker);
- hoursPicker = (WheelHourPicker) findViewById(R.id.hoursPicker);
- amPmPicker = (WheelAmPmPicker) findViewById(R.id.amPmPicker);
+ yearsPicker = findViewById(R.id.yearPicker);
+ monthPicker = findViewById(R.id.monthPicker);
+ daysOfMonthPicker = findViewById(R.id.daysOfMonthPicker);
+ daysPicker = findViewById(R.id.daysPicker);
+ minutesPicker = findViewById(R.id.minutesPicker);
+ hoursPicker = findViewById(R.id.hoursPicker);
+ amPmPicker = findViewById(R.id.amPmPicker);
dtSelector = findViewById(R.id.dtSelector);
pickers.addAll(Arrays.asList(
@@ -119,10 +129,20 @@ public SingleDateAndTimePicker(Context context, AttributeSet attrs, int defStyle
monthPicker,
yearsPicker
));
-
+ for (WheelPicker wheelPicker : pickers) {
+ wheelPicker.setDateHelper(dateHelper);
+ }
init(context, attrs);
}
+ public void setDateHelper(DateHelper dateHelper) {
+ this.dateHelper = dateHelper;
+ }
+
+ public void setTimeZone(TimeZone timeZone) {
+ dateHelper.setTimeZone(timeZone);
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -132,6 +152,10 @@ protected void onAttachedToWindow() {
public void onYearSelected(WheelYearPicker picker, int position, int year) {
updateListener();
checkMinMaxDate(picker);
+
+ if (displayDaysOfMonth) {
+ updateDaysOfMonth();
+ }
}
});
@@ -271,12 +295,29 @@ public void setDisplayMonthNumbers(boolean displayMonthNumbers) {
this.monthPicker.updateAdapter();
}
- public void setTodayText(String todayText) {
- if (todayText != null && !todayText.isEmpty()) {
+ public void setMonthFormat(String monthFormat) {
+ this.monthPicker.setMonthFormat(monthFormat);
+ this.monthPicker.updateAdapter();
+ }
+
+ public void setTodayText(DateWithLabel todayText) {
+ if (todayText != null && todayText.label != null && !todayText.label.isEmpty()) {
daysPicker.setTodayText(todayText);
}
}
+ public void setItemSpacing(int size) {
+ for (WheelPicker picker : pickers) {
+ picker.setItemSpace(size);
+ }
+ }
+
+ public void setCurvedMaxAngle(int angle) {
+ for (WheelPicker picker : pickers) {
+ picker.setCurvedMaxAngle(angle);
+ }
+ }
+
public void setCurved(boolean curved) {
for (WheelPicker picker : pickers) {
picker.setCurved(curved);
@@ -307,6 +348,27 @@ public void setTextColor(int textColor) {
}
}
+ public void setTextAlign(int align) {
+ for (WheelPicker picker : pickers) {
+ picker.setItemAlign(align);
+ }
+ }
+
+ public void setTypeface(Typeface typeface) {
+ if(typeface == null) return;
+ for (WheelPicker picker : pickers) {
+ picker.setTypeface(typeface);
+ }
+ }
+
+ private void setFontToAllPickers(int resourceId) {
+ if (resourceId > 0) {
+ for (int i = 0; i< pickers.size();i++) {
+ pickers.get(i).setTypeface(ResourcesCompat.getFont(getContext(), resourceId));
+ }
+ }
+ }
+
public void setSelectorColor(int selectorColor) {
dtSelector.setBackgroundColor(selectorColor);
}
@@ -330,22 +392,25 @@ public void setIsAmPm(boolean isAmPm) {
hoursPicker.setIsAmPm(isAmPm);
}
+ public boolean isAmPm() {
+ return isAmPm;
+ }
+
public void setDayFormatter(SimpleDateFormat simpleDateFormat) {
if (simpleDateFormat != null) {
this.daysPicker.setDayFormatter(simpleDateFormat);
}
}
- public boolean isAmPm() {
- return isAmPm;
- }
-
public Date getMinDate() {
return minDate;
}
public void setMinDate(Date minDate) {
- this.minDate = minDate;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
+ calendar.setTime(minDate);
+ this.minDate = calendar.getTime();
setMinYear();
}
@@ -354,10 +419,20 @@ public Date getMaxDate() {
}
public void setMaxDate(Date maxDate) {
- this.maxDate = maxDate;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
+ calendar.setTime(maxDate);
+ this.maxDate = calendar.getTime();
setMinYear();
}
+ public void setCustomLocale(Locale locale) {
+ for (WheelPicker p : pickers) {
+ p.setCustomLocale(locale);
+ p.updateAdapter();
+ }
+ }
+
private void checkMinMaxDate(final WheelPicker picker) {
checkBeforeMinDate(picker);
checkAfterMaxDate(picker);
@@ -390,11 +465,11 @@ public void run() {
}
private boolean isBeforeMinDate(Date date) {
- return getCalendarOfDate(date).before(getCalendarOfDate(minDate));
+ return dateHelper.getCalendarOfDate(date).before(dateHelper.getCalendarOfDate(minDate));
}
private boolean isAfterMaxDate(Date date) {
- return getCalendarOfDate(date).after(getCalendarOfDate(maxDate));
+ return dateHelper.getCalendarOfDate(date).after(dateHelper.getCalendarOfDate(maxDate));
}
public void addOnDateChangedListener(OnDateChangedListener listener) {
@@ -419,7 +494,7 @@ public Date getDate() {
final int minute = minutesPicker.getCurrentMinute();
final Calendar calendar = Calendar.getInstance();
-
+ calendar.setTimeZone(dateHelper.getTimeZone());
if (displayDays) {
final Date dayDate = daysPicker.getCurrentDate();
calendar.setTime(dayDate);
@@ -433,27 +508,37 @@ public Date getDate() {
}
if (displayDaysOfMonth) {
- calendar.set(Calendar.DAY_OF_MONTH, daysOfMonthPicker.getCurrentDay() + 1);
+ int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+ if (daysOfMonthPicker.getCurrentDay() >= daysInMonth) {
+ calendar.set(Calendar.DAY_OF_MONTH, daysInMonth);
+ } else {
+ calendar.set(Calendar.DAY_OF_MONTH, daysOfMonthPicker.getCurrentDay() + 1);
+ }
}
}
-
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
-
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
- public void setStepMinutes(int minutesStep) {
- minutesPicker.setStepMinutes(minutesStep);
+ public void setStepSizeMinutes(int minutesStep) {
+ minutesPicker.setStepSizeMinutes(minutesStep);
}
- public void setHoursStep(int hoursStep) {
- hoursPicker.setHoursStep(hoursStep);
+ public void setStepSizeHours(int hoursStep) {
+ hoursPicker.setStepSizeHours(hoursStep);
}
public void setDefaultDate(Date date) {
if (date != null) {
- this.defaultDate = date;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
+ calendar.setTime(date);
+ this.defaultDate = calendar.getTime();
+
+ updateDaysOfMonth(calendar);
for (WheelPicker picker : pickers) {
picker.setDefaultDate(defaultDate);
@@ -488,7 +573,12 @@ private void updateListener() {
private void updateDaysOfMonth() {
final Date date = getDate();
Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
calendar.setTime(date);
+ updateDaysOfMonth(calendar);
+ }
+
+ private void updateDaysOfMonth(@NonNull Calendar calendar) {
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
daysOfMonthPicker.setDaysInMonth(daysInMonth);
daysOfMonthPicker.updateAdapter();
@@ -496,8 +586,11 @@ private void updateDaysOfMonth() {
public void setMustBeOnFuture(boolean mustBeOnFuture) {
this.mustBeOnFuture = mustBeOnFuture;
+ daysPicker.setShowOnlyFutureDate(mustBeOnFuture);
if (mustBeOnFuture) {
- minDate = Calendar.getInstance().getTime(); //minDate is Today
+ Calendar now = Calendar.getInstance();
+ now.setTimeZone(dateHelper.getTimeZone());
+ minDate = now.getTime(); //minDate is Today
}
}
@@ -509,6 +602,7 @@ private void setMinYear() {
if (displayYears && this.minDate != null && this.maxDate != null) {
Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
calendar.setTime(this.minDate);
yearsPicker.setMinYear(calendar.get(Calendar.YEAR));
calendar.setTime(this.maxDate);
@@ -526,17 +620,23 @@ private void init(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SingleDateAndTimePicker);
final Resources resources = getResources();
- setTodayText(a.getString(R.styleable.SingleDateAndTimePicker_picker_todayText));
+ setTodayText(new DateWithLabel(a.getString(R.styleable.SingleDateAndTimePicker_picker_todayText), new Date()));
setTextColor(a.getColor(R.styleable.SingleDateAndTimePicker_picker_textColor, ContextCompat.getColor(context, R.color.picker_default_text_color)));
setSelectedTextColor(a.getColor(R.styleable.SingleDateAndTimePicker_picker_selectedTextColor, ContextCompat.getColor(context, R.color.picker_default_selected_text_color)));
setSelectorColor(a.getColor(R.styleable.SingleDateAndTimePicker_picker_selectorColor, ContextCompat.getColor(context, R.color.picker_default_selector_color)));
+ setItemSpacing(a.getDimensionPixelSize(R.styleable.SingleDateAndTimePicker_picker_itemSpacing, resources.getDimensionPixelSize(R.dimen.wheelSelectorHeight)));
+ setCurvedMaxAngle(a.getInteger(R.styleable.SingleDateAndTimePicker_picker_curvedMaxAngle, WheelPicker.MAX_ANGLE));
setSelectorHeight(a.getDimensionPixelSize(R.styleable.SingleDateAndTimePicker_picker_selectorHeight, resources.getDimensionPixelSize(R.dimen.wheelSelectorHeight)));
setTextSize(a.getDimensionPixelSize(R.styleable.SingleDateAndTimePicker_picker_textSize, resources.getDimensionPixelSize(R.dimen.WheelItemTextSize)));
setCurved(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_curved, IS_CURVED_DEFAULT));
setCyclic(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_cyclic, IS_CYCLIC_DEFAULT));
- setMustBeOnFuture(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_mustBeOnFuture, MUST_BE_ON_FUTUR_DEFAULT));
+ setMustBeOnFuture(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_mustBeOnFuture, MUST_BE_ON_FUTURE_DEFAULT));
setVisibleItemCount(a.getInt(R.styleable.SingleDateAndTimePicker_picker_visibleItemCount, VISIBLE_ITEM_COUNT_DEFAULT));
+ setStepSizeMinutes(a.getInt(R.styleable.SingleDateAndTimePicker_picker_stepSizeMinutes, 1));
+ setStepSizeHours(a.getInt(R.styleable.SingleDateAndTimePicker_picker_stepSizeHours, 1));
+
+ daysPicker.setDayCount(a.getInt(R.styleable.SingleDateAndTimePicker_picker_dayCount, DAYS_PADDING));
setDisplayDays(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayDays, displayDays));
setDisplayMinutes(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayMinutes, displayMinutes));
setDisplayHours(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayHours, displayHours));
@@ -544,15 +644,22 @@ private void init(Context context, AttributeSet attrs) {
setDisplayYears(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayYears, displayYears));
setDisplayDaysOfMonth(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayDaysOfMonth, displayDaysOfMonth));
setDisplayMonthNumbers(a.getBoolean(R.styleable.SingleDateAndTimePicker_picker_displayMonthNumbers, monthPicker.displayMonthNumbers()));
+ setFontToAllPickers(a.getResourceId(R.styleable.SingleDateAndTimePicker_fontFamily,0));
+ setFontToAllPickers(a.getResourceId(R.styleable.SingleDateAndTimePicker_android_fontFamily,0));
+ String monthFormat = a.getString(R.styleable.SingleDateAndTimePicker_picker_monthFormat);
+ setMonthFormat(TextUtils.isEmpty(monthFormat) ? WheelMonthPicker.MONTH_FORMAT : monthFormat);
+ setTextAlign(a.getInt(R.styleable.SingleDateAndTimePicker_picker_textAlign, ALIGN_CENTER));
checkSettings();
setMinYear();
a.recycle();
-
if (displayDaysOfMonth) {
- updateDaysOfMonth();
+ Calendar now = Calendar.getInstance();
+ now.setTimeZone(dateHelper.getTimeZone());
+ updateDaysOfMonth(now);
}
+ daysPicker.updateAdapter(); // For MustBeFuture and dayCount
}
public interface OnDateChangedListener {
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BaseDialog.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BaseDialog.java
index 27199fb6..51f77f70 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BaseDialog.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BaseDialog.java
@@ -1,15 +1,13 @@
package com.github.florent37.singledateandtimepicker.dialog;
import android.graphics.Color;
-import android.support.annotation.ColorInt;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
-import com.github.florent37.singledateandtimepicker.widget.WheelMinutePicker;
-
-import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.STEP_MINUTES_DEFAULT;
@@ -60,6 +58,8 @@ public abstract class BaseDialog {
protected SimpleDateFormat dayFormatter;
+ protected Locale customLocale;
+
public void display() {
this.isDisplaying = true;
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BottomSheetHelper.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BottomSheetHelper.java
index 2c570265..494ea44a 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BottomSheetHelper.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/BottomSheetHelper.java
@@ -28,6 +28,8 @@ public class BottomSheetHelper {
private Handler handler;
private WindowManager windowManager;
+ private boolean focusable;
+
public BottomSheetHelper(Context context, int layoutId) {
this.context = context;
this.layoutId = layoutId;
@@ -43,12 +45,14 @@ public void run() {
view = LayoutInflater.from(context).inflate(layoutId, null, true);
+ // Don't let it grab the input focus if focusable is false
+ int flags = focusable ? 0 : WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
// Shrink the window to wrap the content rather than filling the screen
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
- // Don't let it grab the input focus
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ flags,
// Make the underlying application window visible through any transparent parts
PixelFormat.TRANSLUCENT);
@@ -74,10 +78,11 @@ public void onClick(View view) {
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
- if (listener != null) {
- listener.onLoaded(view);
- }
- return true;
+ if (listener != null) {
+ listener.onLoaded(view);
+ }
+ animateBottomSheet();
+ return false;
}
});
}
@@ -90,25 +95,12 @@ public BottomSheetHelper setListener(Listener listener) {
return this;
}
+ public void setFocusable(boolean focusable) {
+ this.focusable = focusable;
+ }
+
public void display() {
init();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- final ObjectAnimator objectAnimator =
- ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, view.getHeight(), 0);
- objectAnimator.addListener(new AnimatorListenerAdapter() {
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (listener != null) {
- listener.onOpen();
- }
- }
- });
- objectAnimator.start();
- }
- }, 200);
}
public void hide() {
@@ -140,6 +132,21 @@ private void remove() {
if (view.getWindowToken() != null) windowManager.removeView(view);
}
+ private void animateBottomSheet() {
+ final ObjectAnimator objectAnimator =
+ ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, view.getHeight(), 0);
+ objectAnimator.addListener(new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (listener != null) {
+ listener.onOpen();
+ }
+ }
+ });
+ objectAnimator.start();
+ }
+
public interface Listener {
void onOpen();
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/DoubleDateAndTimePickerDialog.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/DoubleDateAndTimePickerDialog.java
index 654cbb0a..54d3c8c3 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/DoubleDateAndTimePickerDialog.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/DoubleDateAndTimePickerDialog.java
@@ -3,21 +3,27 @@
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.StateListDrawable;
-import android.support.annotation.ColorInt;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.TextView;
+import com.github.florent37.singledateandtimepicker.DateHelper;
import com.github.florent37.singledateandtimepicker.R;
import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
+import com.github.florent37.singledateandtimepicker.widget.DateWithLabel;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.STEP_MINUTES_DEFAULT;
@@ -30,11 +36,16 @@ public class DoubleDateAndTimePickerDialog extends BaseDialog {
private TextView buttonTab1;
private SingleDateAndTimePicker pickerTab0;
private SingleDateAndTimePicker pickerTab1;
+ private final DateHelper dateHelper = new DateHelper();
private View tab0;
private View tab1;
@Nullable
private String tab0Text, tab1Text, title;
@Nullable
+ private Integer titleTextSize;
+ @Nullable
+ private Integer bottomSheetHeight;
+ @Nullable
private String todayText;
@Nullable
private String buttonOkText;
@@ -79,25 +90,43 @@ private void init(View view) {
tab0 = view.findViewById(R.id.tab0);
tab1 = view.findViewById(R.id.tab1);
+ if (pickerTab0 != null) {
+ if (bottomSheetHeight != null) {
+ ViewGroup.LayoutParams params = pickerTab0.getLayoutParams();
+ params.height = bottomSheetHeight;
+ pickerTab0.setLayoutParams(params);
+ }
+ }
+
+ if (pickerTab1 != null) {
+ if (bottomSheetHeight != null) {
+ ViewGroup.LayoutParams params = pickerTab1.getLayoutParams();
+ params.height = bottomSheetHeight;
+ pickerTab1.setLayoutParams(params);
+ }
+ }
+
final View titleLayout = view.findViewById(R.id.sheetTitleLayout);
final TextView titleTextView = (TextView) view.findViewById(R.id.sheetTitle);
- if(title != null) {
+ if (title != null) {
if (titleTextView != null) {
titleTextView.setText(title);
if (titleTextColor != null) {
titleTextView.setTextColor(titleTextColor);
}
+ if (titleTextSize != null) {
+ titleTextView.setTextSize(titleTextSize);
+ }
}
if (mainColor != null && titleLayout != null) {
titleLayout.setBackgroundColor(mainColor);
}
- }
- else {
+ } else {
titleLayout.setVisibility(View.GONE);
}
- pickerTab0.setTodayText(todayText);
- pickerTab1.setTodayText(todayText);
+ pickerTab0.setTodayText(new DateWithLabel(todayText, new Date()));
+ pickerTab1.setTodayText(new DateWithLabel(todayText, new Date()));
final View sheetContentLayout = view.findViewById(R.id.sheetContentLayout);
if (sheetContentLayout != null) {
@@ -157,6 +186,10 @@ public void onClick(View view) {
if (mainColor != null) {
buttonOk.setTextColor(mainColor);
}
+
+ if (titleTextSize != null) {
+ buttonOk.setTextSize(titleTextSize);
+ }
}
buttonOk.setOnClickListener(new View.OnClickListener() {
@@ -193,8 +226,8 @@ public void onClick(View view) {
pickerTab0.setMustBeOnFuture(mustBeOnFuture);
pickerTab1.setMustBeOnFuture(mustBeOnFuture);
- pickerTab0.setStepMinutes(minutesStep);
- pickerTab1.setStepMinutes(minutesStep);
+ pickerTab0.setStepSizeMinutes(minutesStep);
+ pickerTab1.setStepSizeMinutes(minutesStep);
if (mainColor != null) {
pickerTab0.setSelectedTextColor(mainColor);
@@ -235,6 +268,11 @@ public void onClick(View view) {
pickerTab1.setDayFormatter(dayFormatter);
}
+ if (customLocale != null) {
+ pickerTab0.setCustomLocale(customLocale);
+ pickerTab1.setCustomLocale(customLocale);
+ }
+
if (secondDateAfterFirst) {
pickerTab0.addOnDateChangedListener(new SingleDateAndTimePicker.OnDateChangedListener() {
@Override
@@ -249,8 +287,8 @@ public void onDateChanged(String displayed, Date date) {
@NonNull
private StateListDrawable getTabsListDrawable() {
final StateListDrawable colorState0 = new StateListDrawable();
- colorState0.addState(new int[] {android.R.attr.state_selected}, new ColorDrawable(mainColor));
- colorState0.addState(new int[] {-android.R.attr.state_selected}, new ColorDrawable(backgroundColor));
+ colorState0.addState(new int[]{android.R.attr.state_selected}, new ColorDrawable(mainColor));
+ colorState0.addState(new int[]{-android.R.attr.state_selected}, new ColorDrawable(backgroundColor));
return colorState0;
}
@@ -274,6 +312,16 @@ public DoubleDateAndTimePickerDialog setTitle(@Nullable String title) {
return this;
}
+ public DoubleDateAndTimePickerDialog setTitleTextSize(@Nullable Integer titleTextSize) {
+ this.titleTextSize = titleTextSize;
+ return this;
+ }
+
+ public DoubleDateAndTimePickerDialog setBottomSheetHeight(@Nullable Integer bottomSheetHeight) {
+ this.bottomSheetHeight = bottomSheetHeight;
+ return this;
+ }
+
public DoubleDateAndTimePickerDialog setTodayText(@Nullable String todayText) {
this.todayText = todayText;
return this;
@@ -319,6 +367,11 @@ public DoubleDateAndTimePickerDialog setDayFormatter(SimpleDateFormat dayFormatt
return this;
}
+ public DoubleDateAndTimePickerDialog setCustomLocale(Locale locale) {
+ this.customLocale = locale;
+ return this;
+ }
+
public DoubleDateAndTimePickerDialog setTab0Date(Date tab0Date) {
this.tab0Date = tab0Date;
return this;
@@ -364,6 +417,18 @@ public DoubleDateAndTimePickerDialog setTab1DisplayMinutes(boolean tab1Minutes)
return this;
}
+ public DoubleDateAndTimePickerDialog setFocusable(boolean focusable) {
+ bottomSheetHelper.setFocusable(focusable);
+ return this;
+ }
+
+ private DoubleDateAndTimePickerDialog setTimeZone(TimeZone timeZone) {
+ dateHelper.setTimeZone(timeZone);
+// pickerTab0.setTimeZone(timeZone);
+// pickerTab1.setTimeZone(timeZone);
+ return this;
+ }
+
@Override
public void display() {
super.display();
@@ -371,7 +436,7 @@ public void display() {
}
@Override
- public void dismiss(){
+ public void dismiss() {
super.dismiss();
bottomSheetHelper.dismiss();
}
@@ -432,6 +497,10 @@ public static class Builder {
@Nullable
private String title;
@Nullable
+ private Integer titleTextSize;
+ @Nullable
+ private Integer bottomSheetHeight;
+ @Nullable
private String buttonOkText;
@Nullable
private String todayText;
@@ -443,6 +512,8 @@ public static class Builder {
private SimpleDateFormat dayFormatter;
+ private Locale customLocale;
+
@ColorInt
@Nullable
private Integer backgroundColor = null;
@@ -472,6 +543,8 @@ public static class Builder {
private boolean tab1Days = true;
private boolean tab1Hours = true;
private boolean tab1Minutes = true;
+ private boolean focusable = false;
+ private TimeZone timeZone;
public Builder(Context context) {
this.context = context;
@@ -482,6 +555,16 @@ public DoubleDateAndTimePickerDialog.Builder title(@Nullable String title) {
return this;
}
+ public DoubleDateAndTimePickerDialog.Builder titleTextSize(@Nullable Integer titleTextSize) {
+ this.titleTextSize = titleTextSize;
+ return this;
+ }
+
+ public DoubleDateAndTimePickerDialog.Builder bottomSheetHeight(@Nullable Integer bottomSheetHeight) {
+ this.bottomSheetHeight = bottomSheetHeight;
+ return this;
+ }
+
public DoubleDateAndTimePickerDialog.Builder todayText(@Nullable String todayText) {
this.todayText = todayText;
return this;
@@ -507,6 +590,11 @@ public DoubleDateAndTimePickerDialog.Builder dayFormatter(SimpleDateFormat dayFo
return this;
}
+ public DoubleDateAndTimePickerDialog.Builder customLocale(Locale locale) {
+ this.customLocale = locale;
+ return this;
+ }
+
public DoubleDateAndTimePickerDialog.Builder minutesStep(int minutesStep) {
this.minutesStep = minutesStep;
return this;
@@ -608,9 +696,21 @@ public DoubleDateAndTimePickerDialog.Builder setTab1DisplayMinutes(boolean tab1M
return this;
}
+ public DoubleDateAndTimePickerDialog.Builder setTimeZone(TimeZone timeZone) {
+ this.timeZone = timeZone;
+ return this;
+ }
+
+ public DoubleDateAndTimePickerDialog.Builder focusable() {
+ this.focusable = true;
+ return this;
+ }
+
public DoubleDateAndTimePickerDialog build() {
final DoubleDateAndTimePickerDialog dialog = new DoubleDateAndTimePickerDialog(context, bottomSheet)
.setTitle(title)
+ .setTitleTextSize(titleTextSize)
+ .setBottomSheetHeight(bottomSheetHeight)
.setTodayText(todayText)
.setListener(listener)
.setCurved(curved)
@@ -630,8 +730,11 @@ public DoubleDateAndTimePickerDialog build() {
.setTab0Date(tab0Date)
.setTab1Date(tab1Date)
.setDayFormatter(dayFormatter)
+ .setCustomLocale(customLocale)
.setMustBeOnFuture(mustBeOnFuture)
- .setSecondDateAfterFirst(secondDateAfterFirst);
+ .setSecondDateAfterFirst(secondDateAfterFirst)
+ .setTimeZone(timeZone)
+ .setFocusable(focusable);
if (mainColor != null) {
dialog.setMainColor(mainColor);
@@ -659,9 +762,10 @@ public void close() {
}
}
- public void dismiss(){
- if(dialog!=null)
+ public void dismiss() {
+ if (dialog != null) {
dialog.dismiss();
+ }
}
}
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/SingleDateAndTimePickerDialog.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/SingleDateAndTimePickerDialog.java
index 8d4edfe6..7307e624 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/SingleDateAndTimePickerDialog.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/dialog/SingleDateAndTimePickerDialog.java
@@ -1,24 +1,29 @@
package com.github.florent37.singledateandtimepicker.dialog;
import android.content.Context;
-import android.support.annotation.ColorInt;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TextView;
+import com.github.florent37.singledateandtimepicker.DateHelper;
import com.github.florent37.singledateandtimepicker.R;
import com.github.florent37.singledateandtimepicker.SingleDateAndTimePicker;
-import com.github.florent37.singledateandtimepicker.widget.WheelMinutePicker;
+import com.github.florent37.singledateandtimepicker.widget.DateWithLabel;
import java.text.SimpleDateFormat;
-import java.util.Calendar;
import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.STEP_MINUTES_DEFAULT;
public class SingleDateAndTimePickerDialog extends BaseDialog {
+ private final DateHelper dateHelper = new DateHelper();
private Listener listener;
private BottomSheetHelper bottomSheetHelper;
private SingleDateAndTimePicker picker;
@@ -26,6 +31,10 @@ public class SingleDateAndTimePickerDialog extends BaseDialog {
@Nullable
private String title;
@Nullable
+ private Integer titleTextSize;
+ @Nullable
+ private Integer bottomSheetHeight;
+ @Nullable
private String todayText;
@Nullable
private DisplayListener displayListener;
@@ -55,6 +64,10 @@ public void onLoaded(View view) {
@Override
public void onClose() {
SingleDateAndTimePickerDialog.this.onClose();
+
+ if (displayListener != null) {
+ displayListener.onClosed(picker);
+ }
}
});
}
@@ -62,6 +75,14 @@ public void onClose() {
private void init(View view) {
picker = (SingleDateAndTimePicker) view.findViewById(R.id.picker);
+ picker.setDateHelper(dateHelper);
+ if (picker != null) {
+ if (bottomSheetHeight != null) {
+ ViewGroup.LayoutParams params = picker.getLayoutParams();
+ params.height = bottomSheetHeight;
+ picker.setLayoutParams(params);
+ }
+ }
final TextView buttonOk = (TextView) view.findViewById(R.id.buttonOk);
if (buttonOk != null) {
@@ -76,6 +97,10 @@ public void onClick(View view) {
if (mainColor != null) {
buttonOk.setTextColor(mainColor);
}
+
+ if (titleTextSize != null) {
+ buttonOk.setTextSize(titleTextSize);
+ }
}
final View sheetContentLayout = view.findViewById(R.id.sheetContentLayout);
@@ -99,9 +124,13 @@ public void onClick(View v) {
if (titleTextColor != null) {
titleTextView.setTextColor(titleTextColor);
}
+
+ if (titleTextSize != null) {
+ titleTextView.setTextSize(titleTextSize);
+ }
}
- picker.setTodayText(todayText);
+ picker.setTodayText(new DateWithLabel(todayText, new Date()));
final View pickerTitleHeader = view.findViewById(R.id.pickerTitleHeader);
if (mainColor != null && pickerTitleHeader != null) {
@@ -117,16 +146,23 @@ public void onClick(View v) {
}
picker.setMustBeOnFuture(mustBeOnFuture);
- picker.setStepMinutes(minutesStep);
+ picker.setStepSizeMinutes(minutesStep);
if (dayFormatter != null) {
picker.setDayFormatter(dayFormatter);
}
+ if (customLocale != null) {
+ picker.setCustomLocale(customLocale);
+ }
+
if (mainColor != null) {
picker.setSelectedTextColor(mainColor);
}
+ // displayYears used in setMinDate / setMaxDate
+ picker.setDisplayYears(displayYears);
+
if (minDate != null) {
picker.setMinDate(minDate);
}
@@ -144,12 +180,10 @@ public void onClick(View v) {
}
picker.setDisplayDays(displayDays);
- picker.setDisplayYears(displayYears);
picker.setDisplayMonths(displayMonth);
picker.setDisplayDaysOfMonth(displayDaysOfMonth);
picker.setDisplayMinutes(displayMinutes);
picker.setDisplayHours(displayHours);
- picker.setDisplayMonthNumbers(displayMonthNumbers);
}
public SingleDateAndTimePickerDialog setListener(Listener listener) {
@@ -176,6 +210,16 @@ public SingleDateAndTimePickerDialog setTitle(@Nullable String title) {
return this;
}
+ public SingleDateAndTimePickerDialog setTitleTextSize(@Nullable Integer titleTextSize) {
+ this.titleTextSize = titleTextSize;
+ return this;
+ }
+
+ public SingleDateAndTimePickerDialog setBottomSheetHeight(@Nullable Integer bottomSheetHeight) {
+ this.bottomSheetHeight = bottomSheetHeight;
+ return this;
+ }
+
public SingleDateAndTimePickerDialog setTodayText(@Nullable String todayText) {
this.todayText = todayText;
return this;
@@ -242,11 +286,26 @@ public SingleDateAndTimePickerDialog setDayFormatter(SimpleDateFormat dayFormatt
return this;
}
+ public SingleDateAndTimePickerDialog setCustomLocale(Locale locale) {
+ this.customLocale = locale;
+ return this;
+ }
+
public SingleDateAndTimePickerDialog setIsAmPm(boolean isAmPm) {
this.isAmPm = Boolean.valueOf(isAmPm);
return this;
}
+ public SingleDateAndTimePickerDialog setFocusable(boolean focusable) {
+ bottomSheetHelper.setFocusable(focusable);
+ return this;
+ }
+
+ private SingleDateAndTimePickerDialog setTimeZone(TimeZone timeZone) {
+ dateHelper.setTimeZone(timeZone);
+ return this;
+ }
+
@Override
public void display() {
super.display();
@@ -275,6 +334,7 @@ public interface Listener {
public interface DisplayListener {
void onDisplayed(SingleDateAndTimePicker picker);
+ void onClosed(SingleDateAndTimePicker picker);
}
public static class Builder {
@@ -289,6 +349,12 @@ public static class Builder {
@Nullable
private String title;
+ @Nullable
+ private Integer titleTextSize;
+
+ @Nullable
+ private Integer bottomSheetHeight;
+
@Nullable
private String todayText;
@@ -305,6 +371,7 @@ public static class Builder {
private boolean displayDaysOfMonth = false;
private boolean displayYears = false;
private boolean displayMonthNumbers = false;
+ private boolean focusable = false;
@Nullable
private Boolean isAmPm;
@@ -331,6 +398,10 @@ public static class Builder {
@Nullable
private SimpleDateFormat dayFormatter;
+ @Nullable
+ private Locale customLocale;
+ private TimeZone timeZone;
+
public Builder(Context context) {
this.context = context;
}
@@ -340,6 +411,16 @@ public Builder title(@Nullable String title) {
return this;
}
+ public Builder titleTextSize(@Nullable Integer titleTextSize) {
+ this.titleTextSize = titleTextSize;
+ return this;
+ }
+
+ public Builder bottomSheetHeight(@Nullable Integer bottomSheetHeight) {
+ this.bottomSheetHeight = bottomSheetHeight;
+ return this;
+ }
+
public Builder todayText(@Nullable String todayText) {
this.todayText = todayText;
return this;
@@ -450,9 +531,26 @@ public Builder setDayFormatter(SimpleDateFormat dayFormatter) {
return this;
}
+ public Builder customLocale(Locale locale) {
+ this.customLocale = locale;
+ return this;
+ }
+
+ public Builder setTimeZone(TimeZone timeZone) {
+ this.timeZone = timeZone;
+ return this;
+ }
+
+ public Builder focusable() {
+ this.focusable = true;
+ return this;
+ }
+
public SingleDateAndTimePickerDialog build() {
final SingleDateAndTimePickerDialog dialog = new SingleDateAndTimePickerDialog(context, bottomSheet)
.setTitle(title)
+ .setTitleTextSize(titleTextSize)
+ .setBottomSheetHeight(bottomSheetHeight)
.setTodayText(todayText)
.setListener(listener)
.setCurved(curved)
@@ -468,7 +566,10 @@ public SingleDateAndTimePickerDialog build() {
.setDisplayMonthNumbers(displayMonthNumbers)
.setDisplayDays(displayDays)
.setDayFormatter(dayFormatter)
- .setMustBeOnFuture(mustBeOnFuture);
+ .setCustomLocale(customLocale)
+ .setMustBeOnFuture(mustBeOnFuture)
+ .setTimeZone(timeZone)
+ .setFocusable(focusable);
if (mainColor != null) {
dialog.setMainColor(mainColor);
@@ -509,4 +610,5 @@ public void dismiss() {
dialog.dismiss();
}
}
+
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/DateWithLabel.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/DateWithLabel.java
new file mode 100644
index 00000000..a61c3f3b
--- /dev/null
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/DateWithLabel.java
@@ -0,0 +1,37 @@
+package com.github.florent37.singledateandtimepicker.widget;
+
+import com.github.florent37.singledateandtimepicker.DateHelper;
+
+import java.util.Date;
+
+public class DateWithLabel {
+ public final String label;
+ public final Date date;
+
+ public DateWithLabel(String label, Date date) {
+ this.label = label;
+ this.date = date;
+ if (date == null) {
+ throw new IllegalArgumentException("null value provided. " + "label=[" + label + "], date=[" + date + "]");
+ }
+ }
+
+ @Override
+ public String toString() {
+ return label;
+ }
+
+ @Override
+ public int hashCode() {
+ throw new IllegalStateException("Not implemented");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof DateWithLabel) {
+ DateWithLabel newDate = (DateWithLabel) o;
+ return label.equals(newDate.label) && DateHelper.compareDateIgnoreTime(date, newDate.date) == 0;
+ }
+ return false;
+ }
+}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/SingleDateAndTimeConstants.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/SingleDateAndTimeConstants.java
index f22b2e56..9cc3e3bb 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/SingleDateAndTimeConstants.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/SingleDateAndTimeConstants.java
@@ -12,6 +12,6 @@ public class SingleDateAndTimeConstants {
public static final int MAX_MINUTES = 59;
public static final int STEP_MINUTES_DEFAULT = 5;
- public static final int MIN_YEAR_DIFF = 20;
- public static final int MAX_YEAR_DIFF = 20;
+ public static final int MIN_YEAR_DIFF = 150;
+ public static final int MAX_YEAR_DIFF = 100;
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelAmPmPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelAmPmPicker.java
index 3ff8875d..e33d31fb 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelAmPmPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelAmPmPicker.java
@@ -1,11 +1,8 @@
package com.github.florent37.singledateandtimepicker.widget;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
-import com.github.florent37.singledateandtimepicker.DateHelper;
import com.github.florent37.singledateandtimepicker.R;
import java.util.Arrays;
@@ -13,6 +10,9 @@
import java.util.Date;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
public class WheelAmPmPicker extends WheelPicker {
public static final int INDEX_AM = 0;
@@ -36,24 +36,27 @@ protected void init() {
@Override
protected String initDefault() {
- if (DateHelper.getHour(DateHelper.today(), true) >= SingleDateAndTimeConstants.MAX_HOUR_AM_PM) {
- return getContext().getString(R.string.picker_pm);
+ if (dateHelper.getHour(dateHelper.today(), true) >= SingleDateAndTimeConstants.MAX_HOUR_AM_PM) {
+ return getLocalizedString(R.string.picker_pm);
} else {
- return getContext().getString(R.string.picker_am);
+ return getLocalizedString(R.string.picker_am);
}
}
@Override
- protected List generateAdapterValues(){
+ protected List generateAdapterValues(boolean showOnlyFutureDates){
return Arrays.asList(
- getContext().getString(R.string.picker_am),
- getContext().getString(R.string.picker_pm)
+ getLocalizedString(R.string.picker_am),
+ getLocalizedString(R.string.picker_pm)
);
}
@Override
public int findIndexOfDate(@NonNull Date date) {
- final int hours = date.getHours();
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
+ calendar.setTime(date);
+ final int hours = calendar.get(Calendar.HOUR_OF_DAY);
if (hours >= SingleDateAndTimeConstants.MAX_HOUR_AM_PM) {
return 1;
} else {
@@ -87,8 +90,9 @@ public boolean isAmPosition(int position) {
protected String getFormattedValue(Object value) {
if (value instanceof Date) {
Calendar instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
instance.setTime((Date) value);
- return getResources().getString(instance.get(Calendar.AM_PM) == Calendar.PM ? R.string.picker_pm : R.string.picker_am);
+ return getLocalizedString(instance.get(Calendar.AM_PM) == Calendar.PM ? R.string.picker_pm : R.string.picker_am);
}
return String.valueOf(value);
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayOfMonthPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayOfMonthPicker.java
index b3d92d8d..025650da 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayOfMonthPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayOfMonthPicker.java
@@ -6,9 +6,6 @@
import java.util.ArrayList;
import java.util.List;
-import static com.github.florent37.singledateandtimepicker.DateHelper.getDay;
-import static com.github.florent37.singledateandtimepicker.DateHelper.today;
-
public class WheelDayOfMonthPicker extends WheelPicker {
private int daysInMonth;
@@ -29,7 +26,7 @@ protected void init() {
}
@Override
- protected List generateAdapterValues() {
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
final List dayList = new ArrayList<>();
for (int i = 1; i <= daysInMonth; i++) {
@@ -42,7 +39,7 @@ protected List generateAdapterValues() {
@Override
protected String initDefault() {
- return String.valueOf(getDay(today()));
+ return String.valueOf(dateHelper.getDay(dateHelper.today()));
}
public void setOnFinishedLoopListener(FinishedLoopListener finishedLoopListener) {
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayPicker.java
index 7663c6db..c64dca48 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelDayPicker.java
@@ -1,30 +1,31 @@
package com.github.florent37.singledateandtimepicker.widget;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
import android.util.AttributeSet;
-import com.github.florent37.singledateandtimepicker.DateHelper;
import com.github.florent37.singledateandtimepicker.R;
-import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
-import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.*;
+import androidx.annotation.NonNull;
-public class WheelDayPicker extends WheelPicker {
+import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.DAYS_PADDING;
+
+public class WheelDayPicker extends WheelPicker {
+
+ private static final String DAY_FORMAT_PATTERN = "EEE d MMM";
private SimpleDateFormat simpleDateFormat;
+ private SimpleDateFormat customDateFormat;
+ private int dayCount = DAYS_PADDING;
private OnDaySelectedListener onDaySelectedListener;
- private String todayText;
-
public WheelDayPicker(Context context) {
super(context);
}
@@ -35,55 +36,76 @@ public WheelDayPicker(Context context, AttributeSet attrs) {
@Override
protected void init() {
- simpleDateFormat = new SimpleDateFormat("EEE d MMM", getCurrentLocale());
+ simpleDateFormat = new SimpleDateFormat(DAY_FORMAT_PATTERN, getCurrentLocale());
+ simpleDateFormat.setTimeZone(dateHelper.getTimeZone());
}
@Override
- protected String initDefault() {
- return getTodayText();
+ public void setCustomLocale(Locale customLocale) {
+ super.setCustomLocale(customLocale);
+ simpleDateFormat = new SimpleDateFormat(DAY_FORMAT_PATTERN, getCurrentLocale());
+ simpleDateFormat.setTimeZone(dateHelper.getTimeZone());
}
- public WheelDayPicker setDayFormatter(SimpleDateFormat simpleDateFormat){
- this.simpleDateFormat = simpleDateFormat;
- adapter.setData(generateAdapterValues());
- notifyDatasetChanged();
- return this;
+ @Override
+ protected DateWithLabel initDefault() {
+ return new DateWithLabel(getTodayText(), new Date());
+ }
+
+ @NonNull
+ private String getTodayText() {
+ return getLocalizedString(R.string.picker_today);
}
@Override
- protected void onItemSelected(int position, String item) {
+ protected void onItemSelected(int position, DateWithLabel item) {
if (onDaySelectedListener != null) {
- final Date date = convertItemToDate(position);
- onDaySelectedListener.onDaySelected(this, position, item, date);
+ onDaySelectedListener.onDaySelected(this, position, item.label, item.date);
}
}
+ public void setDayCount(int dayCount) {
+ this.dayCount = dayCount;
+ }
+
@Override
- protected List generateAdapterValues() {
- final List days = new ArrayList<>();
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
+ final List days = new ArrayList<>();
Calendar instance = Calendar.getInstance();
- instance.add(Calendar.DATE, -1 * DAYS_PADDING - 1);
- for (int i = (-1) * DAYS_PADDING; i < 0; ++i) {
+ instance.setTimeZone(dateHelper.getTimeZone());
+ int startDayOffset = showOnlyFutureDates ? 0 : -1 * dayCount;
+ instance.add(Calendar.DATE, startDayOffset - 1);
+ for (int i = startDayOffset; i < 0; ++i) {
instance.add(Calendar.DAY_OF_MONTH, 1);
- days.add(getFormattedValue(instance.getTime()));
+ Date date = instance.getTime();
+ days.add(new DateWithLabel(getFormattedValue(date), date));
}
//today
- days.add(getTodayText());
+ days.add(new DateWithLabel(getTodayText(), new Date()));
instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
- for (int i = 0; i < DAYS_PADDING; ++i) {
+ for (int i = 0; i < dayCount; ++i) {
instance.add(Calendar.DATE, 1);
- days.add(getFormattedValue(instance.getTime()));
+ Date date = instance.getTime();
+ days.add(new DateWithLabel(getFormattedValue(date), date));
}
return days;
}
protected String getFormattedValue(Object value) {
- return simpleDateFormat.format(value);
+ return getDateFormat().format(value);
+ }
+
+ public WheelDayPicker setDayFormatter(SimpleDateFormat simpleDateFormat) {
+ simpleDateFormat.setTimeZone(dateHelper.getTimeZone());
+ this.customDateFormat = simpleDateFormat;
+ updateAdapter();
+ return this;
}
public void setOnDaySelectedListener(OnDaySelectedListener onDaySelectedListener) {
@@ -94,51 +116,45 @@ public Date getCurrentDate() {
return convertItemToDate(super.getCurrentItemPosition());
}
+ private SimpleDateFormat getDateFormat() {
+ if (customDateFormat != null) {
+ return customDateFormat;
+ }
+ return simpleDateFormat;
+ }
+
private Date convertItemToDate(int itemPosition) {
- Date date = null;
+ Date date;
final String itemText = adapter.getItemText(itemPosition);
final Calendar todayCalendar = Calendar.getInstance();
+ todayCalendar.setTimeZone(dateHelper.getTimeZone());
- final int todayPosition = adapter.getData().indexOf(getTodayText());
+ int todayPosition = -1;
+ final List data = adapter.getData();
- if (getTodayText().equals(itemText)) {
- date = todayCalendar.getTime();
- } else {
- try {
- date = simpleDateFormat.parse(itemText);
- } catch (ParseException e) {
- e.printStackTrace();
+ for (int i = 0; i < data.size(); i++) {
+ if (data.get(i).label.equals(getTodayText())) {
+ todayPosition = i;
+ break;
}
}
- if (date != null) {
- //try to know the year
- final Calendar dateCalendar = DateHelper.getCalendarOfDate(date);
-
- todayCalendar.add(Calendar.DATE, (itemPosition - todayPosition));
-
- dateCalendar.set(Calendar.YEAR, todayCalendar.get(Calendar.YEAR));
- date = dateCalendar.getTime();
+ if (getTodayText().equals(itemText)) {
+ date = todayCalendar.getTime();
+ } else {
+ todayCalendar.add(Calendar.DAY_OF_YEAR, (itemPosition - todayPosition));
+ date = todayCalendar.getTime();
}
-
return date;
}
- public int getTodayTextPosition() {
- return adapter.getData().indexOf(getTodayText());
- }
-
- @NonNull
- private String getTodayText() {
- return TextUtils.isEmpty(todayText) ? getResources().getString(R.string.picker_today) : todayText;
- }
-
- public void setTodayText(String todayText) {
- int index = getTodayTextPosition();
- if (index != -1) {
- adapter.getData().set(index, todayText);
- notifyDatasetChanged();
- this.todayText = todayText;
+ public void setTodayText(DateWithLabel today) {
+ final List data = adapter.getData();
+ for (int i = 0; i < data.size(); i++) {
+ if (data.get(i).label.equals(getTodayText())) {
+ adapter.getData().set(i, today);
+ notifyDatasetChanged();
+ }
}
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelHourPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelHourPicker.java
index be9cb84f..cc5380c9 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelHourPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelHourPicker.java
@@ -1,21 +1,19 @@
package com.github.florent37.singledateandtimepicker.widget;
import android.content.Context;
-import android.support.annotation.NonNull;
import android.util.AttributeSet;
-import com.github.florent37.singledateandtimepicker.DateHelper;
-
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
-import static com.github.florent37.singledateandtimepicker.DateHelper.getHour;
-import static com.github.florent37.singledateandtimepicker.DateHelper.today;
-import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.*;
+import androidx.annotation.NonNull;
+
+import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.MAX_HOUR_AM_PM;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.MAX_HOUR_DEFAULT;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.MIN_HOUR_DEFAULT;
+import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.STEP_HOURS_DEFAULT;
public class WheelHourPicker extends WheelPicker {
@@ -45,11 +43,11 @@ protected void init() {
@Override
protected String initDefault() {
- return String.valueOf(getHour(today(), isAmPm));
+ return String.valueOf(dateHelper.getHour(dateHelper.today(), isAmPm));
}
@Override
- protected List generateAdapterValues() {
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
final List hours = new ArrayList<>();
if (isAmPm) {
@@ -83,6 +81,7 @@ protected String getFormattedValue(Object value) {
Object valueItem = value;
if (value instanceof Date) {
Calendar instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
instance.setTime((Date) value);
valueItem = instance.get(Calendar.HOUR_OF_DAY);
}
@@ -127,7 +126,7 @@ public void setMinHour(int minHour) {
notifyDatasetChanged();
}
- public void setHoursStep(int hoursStep) {
+ public void setStepSizeHours(int hoursStep) {
if (hoursStep >= MIN_HOUR_DEFAULT && hoursStep <= MAX_HOUR_DEFAULT) {
this.hoursStep = hoursStep;
}
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMinutePicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMinutePicker.java
index 86fedcde..81f4b8dd 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMinutePicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMinutePicker.java
@@ -1,16 +1,15 @@
package com.github.florent37.singledateandtimepicker.widget;
import android.content.Context;
-import android.support.annotation.NonNull;
import android.util.AttributeSet;
-import com.github.florent37.singledateandtimepicker.DateHelper;
-
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import androidx.annotation.NonNull;
+
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.MAX_MINUTES;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.MIN_MINUTES;
import static com.github.florent37.singledateandtimepicker.widget.SingleDateAndTimeConstants.STEP_MINUTES_DEFAULT;
@@ -37,11 +36,13 @@ protected void init() {
@Override
protected String initDefault() {
- return getFormattedValue(Calendar.getInstance().get(Calendar.MINUTE));
+ Calendar now = Calendar.getInstance();
+ now.setTimeZone(dateHelper.getTimeZone());
+ return getFormattedValue(now.get(Calendar.MINUTE));
}
@Override
- protected List generateAdapterValues() {
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
final List minutes = new ArrayList<>();
for (int min = MIN_MINUTES; min <= MAX_MINUTES; min += stepMinutes) {
minutes.add(getFormattedValue(min));
@@ -54,29 +55,36 @@ private int findIndexOfMinute(int minute) {
for (int i = 0; i < itemCount; ++i) {
final String object = adapter.getItemText(i);
final Integer value = Integer.valueOf(object);
+
+ if (minute == value) {
+ return i;
+ }
+
if (minute < value) {
return i - 1;
}
}
- return 0;
+ return itemCount - 1;
+
}
@Override
public int findIndexOfDate(@NonNull Date date) {
- return findIndexOfMinute(DateHelper.getMinuteOf(date));
+ return findIndexOfMinute(dateHelper.getMinuteOf(date));
}
protected String getFormattedValue(Object value) {
Object valueItem = value;
if (value instanceof Date) {
final Calendar instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
instance.setTime((Date) value);
valueItem = instance.get(Calendar.MINUTE);
}
return String.format(getCurrentLocale(), FORMAT, valueItem);
}
- public void setStepMinutes(int stepMinutes) {
+ public void setStepSizeMinutes(int stepMinutes) {
if (stepMinutes < 60 && stepMinutes > 0) {
this.stepMinutes = stepMinutes;
updateAdapter();
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMonthPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMonthPicker.java
index 6e093291..59168146 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMonthPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelMonthPicker.java
@@ -1,19 +1,13 @@
package com.github.florent37.singledateandtimepicker.widget;
import android.content.Context;
+import android.text.TextUtils;
import android.util.AttributeSet;
-import com.github.florent37.singledateandtimepicker.DateHelper;
-
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Date;
import java.util.List;
-import java.util.Locale;
-
-import static com.github.florent37.singledateandtimepicker.DateHelper.getMonth;
-import static com.github.florent37.singledateandtimepicker.DateHelper.today;
public class WheelMonthPicker extends WheelPicker {
@@ -23,6 +17,10 @@ public class WheelMonthPicker extends WheelPicker {
private boolean displayMonthNumbers = false;
+ public static final String MONTH_FORMAT = "MMMM";
+
+ private String monthFormat;
+
public WheelMonthPicker(Context context) {
this(context, null);
}
@@ -37,11 +35,13 @@ protected void init() {
}
@Override
- protected List generateAdapterValues() {
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
final List monthList = new ArrayList<>();
- final SimpleDateFormat month_date = new SimpleDateFormat("MMMM", Locale.getDefault());
- final Calendar cal = Calendar.getInstance(Locale.getDefault());
+ final SimpleDateFormat month_date = new SimpleDateFormat(getMonthFormat(), getCurrentLocale());
+ final Calendar cal = Calendar.getInstance(getCurrentLocale());
+ cal.setTimeZone(dateHelper.getTimeZone());
+ cal.set(Calendar.DAY_OF_MONTH, 1);
for (int i = 0; i < 12; i++) {
cal.set(Calendar.MONTH, i);
@@ -58,7 +58,7 @@ protected List generateAdapterValues() {
@Override
protected String initDefault() {
- return String.valueOf(getMonth(today()));
+ return String.valueOf(dateHelper.getMonth(dateHelper.today()));
}
public void setOnMonthSelectedListener(MonthSelectedListener listener) {
@@ -95,4 +95,21 @@ public int getCurrentMonth() {
public interface MonthSelectedListener {
void onMonthSelected(WheelMonthPicker picker, int monthIndex, String monthName);
}
+
+ public void setMonthFormat(String format)
+ {
+ this.monthFormat = format;
+ }
+
+ public String getMonthFormat()
+ {
+ if(TextUtils.isEmpty(this.monthFormat))
+ {
+ return MONTH_FORMAT;
+ }
+ else
+ {
+ return this.monthFormat;
+ }
+ }
}
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelPicker.java
index 3ca87546..10f96f96 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelPicker.java
@@ -15,7 +15,6 @@
import android.graphics.Typeface;
import android.os.Build;
import android.os.Handler;
-import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -24,6 +23,8 @@
import android.view.ViewConfiguration;
import android.widget.Scroller;
+import com.github.florent37.singledateandtimepicker.DateHelper;
+import com.github.florent37.singledateandtimepicker.LocaleHelper;
import com.github.florent37.singledateandtimepicker.R;
import java.util.ArrayList;
@@ -32,6 +33,9 @@
import java.util.List;
import java.util.Locale;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
public abstract class WheelPicker extends View {
public static final int SCROLL_STATE_IDLE = 0;
@@ -40,12 +44,15 @@ public abstract class WheelPicker extends View {
public static final int ALIGN_CENTER = 0;
public static final int ALIGN_LEFT = 1;
public static final int ALIGN_RIGHT = 2;
+ public static final int MAX_ANGLE = 90;
protected final static String FORMAT = "%1$02d"; // two digits
+ protected DateHelper dateHelper = new DateHelper(); // Overwritten from Single..Picker
private final Handler handler = new Handler();
protected V defaultValue;
protected int lastScrollPosition;
protected Listener listener;
protected Adapter adapter = new Adapter<>();
+ private Locale customLocale;
private Paint paint;
private Scroller scroller;
private VelocityTracker tracker;
@@ -69,6 +76,7 @@ public abstract class WheelPicker extends View {
private int mIndicatorColor;
private int mCurtainColor;
private int mItemSpace;
+ private int mMaxAngle = MAX_ANGLE;
private int mItemAlign;
private int mItemHeight, mHalfItemHeight;
private int mHalfWheelHeight;
@@ -90,6 +98,7 @@ public abstract class WheelPicker extends View {
private boolean hasAtmospheric;
private boolean isCyclic;
private boolean isCurved;
+ private boolean showOnlyFutureDate;
private boolean isClick;
private boolean isForceFinishScroll;
@@ -174,7 +183,7 @@ public WheelPicker(Context context, AttributeSet attrs) {
init();
defaultValue = initDefault();
- adapter.setData(generateAdapterValues());
+ adapter.setData(generateAdapterValues(showOnlyFutureDate));
currentItemPosition = adapter.getItemPosition(defaultValue);
selectedItemPosition = currentItemPosition;
}
@@ -184,11 +193,11 @@ public WheelPicker(Context context, AttributeSet attrs) {
protected abstract V initDefault();
public void updateAdapter() {
- adapter.setData(generateAdapterValues());
+ adapter.setData(generateAdapterValues(showOnlyFutureDate));
notifyDatasetChanged();
}
- protected abstract List generateAdapterValues();
+ protected abstract List generateAdapterValues(boolean showOnlyFutureDates);
@Override
protected void onAttachedToWindow() {
@@ -253,8 +262,10 @@ public void setDefault(V defaultValue) {
public void setDefaultDate(Date date) {
if (adapter != null && adapter.getItemCount() > 0) {
final int indexOfDate = findIndexOfDate(date);
- this.defaultValue = adapter.getData().get(indexOfDate);
- setSelectedItemPosition(indexOfDate);
+ if (indexOfDate >= 0) {
+ this.defaultValue = adapter.getData().get(indexOfDate);
+ setSelectedItemPosition(indexOfDate);
+ }
}
}
@@ -266,6 +277,10 @@ public void setListener(Listener listener) {
this.listener = listener;
}
+ public void setCustomLocale(Locale customLocale) {
+ this.customLocale = customLocale;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
@@ -280,7 +295,10 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Correct view sizes again if curved is enable
if (isCurved) {
- resultHeight = (int) (2 * resultHeight / Math.PI);
+ // The text is written on the circle circumference from -mMaxAngle to mMaxAngle.
+ // 2 * sinDegree(mMaxAngle): Height of drawn circle
+ // Math.PI: Circumference of half unit circle, `mMaxAngle / 90f`: The ratio of half-circle we draw on
+ resultHeight = (int) (2 * sinDegree(mMaxAngle) / (Math.PI * mMaxAngle / 90f) * resultHeight);
}
// Consideration padding influence the view sizes
@@ -375,8 +393,9 @@ private void computeCurrentItemRect() {
@Override
protected void onDraw(Canvas canvas) {
if (null != onWheelChangeListener) onWheelChangeListener.onWheelScrolled(scrollOffsetY);
- if (mItemHeight - mHalfDrawnItemCount <= 0)
+ if (mItemHeight - mHalfDrawnItemCount <= 0) {
return;
+ }
int drawnDataStartPos = -scrollOffsetY / mItemHeight - mHalfDrawnItemCount;
for (int drawnDataPos = drawnDataStartPos + selectedItemPosition,
drawnOffsetPos = -mHalfDrawnItemCount;
@@ -398,7 +417,7 @@ protected void onDraw(Canvas canvas) {
int mDrawnItemCenterY = drawnCenterY + (drawnOffsetPos * mItemHeight) +
scrollOffsetY % mItemHeight;
- int distanceToCenter = 0;
+ float distanceToCenter = 0;
if (isCurved) {
// Correct ratio of item's drawn center to wheel center
float ratio = (drawnCenterY - Math.abs(drawnCenterY - mDrawnItemCenterY) -
@@ -410,12 +429,10 @@ protected void onDraw(Canvas canvas) {
unit = 1;
} else if (mDrawnItemCenterY < drawnCenterY) unit = -1;
- float degree = (-(1 - ratio) * 90 * unit);
- if (degree < -90) degree = -90;
- if (degree > 90) degree = 90;
- distanceToCenter = computeSpace((int) degree);
+ float degree = clamp((-(1 - ratio) * mMaxAngle * unit), -mMaxAngle, mMaxAngle);
+ distanceToCenter = computeYCoordinateAtAngle(degree);
- int transX = wheelCenterX;
+ float transX = wheelCenterX;
switch (mItemAlign) {
case ALIGN_LEFT:
transX = rectDrawn.left;
@@ -424,7 +441,7 @@ protected void onDraw(Canvas canvas) {
transX = rectDrawn.right;
break;
}
- int transY = wheelCenterY - distanceToCenter;
+ float transY = wheelCenterY - distanceToCenter;
camera.save();
camera.rotateX(degree);
@@ -450,7 +467,7 @@ protected void onDraw(Canvas canvas) {
paint.setAlpha(alpha);
}
// Correct item's drawn centerY base on curved state
- int drawnCenterY = isCurved ? this.drawnCenterY - distanceToCenter : mDrawnItemCenterY;
+ float drawnCenterY = isCurved ? this.drawnCenterY - distanceToCenter : mDrawnItemCenterY;
// Judges need to draw different color for current item or not
if (mSelectedItemTextColor != -1) {
@@ -493,12 +510,23 @@ private boolean isPosInRang(int position) {
return position >= 0 && position < adapter.getItemCount();
}
- private int computeSpace(int degree) {
- return (int) (Math.sin(Math.toRadians(degree)) * mHalfWheelHeight);
+ private float computeYCoordinateAtAngle(float degree) {
+ // Compute y-coordinate for item at degree. mMaxAngle is at mHalfWheelHeight
+ return sinDegree(degree) / sinDegree(mMaxAngle) * mHalfWheelHeight;
+ }
+
+ private float sinDegree(float degree) {
+ return (float) Math.sin(Math.toRadians(degree));
}
- private int computeDepth(int degree) {
- return (int) (mHalfWheelHeight - Math.cos(Math.toRadians(degree)) * mHalfWheelHeight);
+ private float computeDepth(float degree) {
+ return (float) (mHalfWheelHeight - Math.cos(Math.toRadians(degree)) * mHalfWheelHeight);
+ }
+
+ private float clamp(float value, float min, float max) {
+ if (value < min) return min;
+ if (value > max) return max;
+ return value;
}
@Override
@@ -704,6 +732,19 @@ public int getDefaultItemPosition() {
return adapter.getData().indexOf(defaultValue);
}
+ public int getTodayItemPosition() {
+ List list = adapter.getData();
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i) instanceof DateWithLabel) {
+ DateWithLabel dwl = (DateWithLabel) list.get(i);
+ if (dwl.label.equals(getLocalizedString(R.string.picker_today))) {
+ return i;
+ }
+ }
+ }
+ return 0;
+ }
+
public void setAdapter(Adapter adapter) {
this.adapter = adapter;
@@ -814,6 +855,12 @@ public void setItemSpace(int space) {
postInvalidate();
}
+ public void setCurvedMaxAngle(int maxAngle) {
+ this.mMaxAngle = maxAngle;
+ requestLayout();
+ postInvalidate();
+ }
+
public void setIndicator(boolean hasIndicator) {
this.hasIndicator = hasIndicator;
computeIndicatorRect();
@@ -918,21 +965,23 @@ public void setTypeface(Typeface tf) {
public int findIndexOfDate(@NonNull Date date) {
String formatItem = getFormattedValue(date);
- if(this instanceof WheelDayOfMonthPicker){
+ if (this instanceof WheelDayOfMonthPicker) {
Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
calendar.setTime(date);
- return calendar.get(Calendar.DAY_OF_MONTH) - 1 ;
+ return calendar.get(Calendar.DAY_OF_MONTH) - 1;
}
if (this instanceof WheelDayPicker) {
String today = getFormattedValue(new Date());
if (today.equals(formatItem)) {
- return ((WheelDayPicker)this).getTodayTextPosition();
+ return getTodayItemPosition();
}
}
if (this instanceof WheelMonthPicker) {
Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
calendar.setTime(date);
return calendar.get(Calendar.MONTH);
}
@@ -940,6 +989,7 @@ public int findIndexOfDate(@NonNull Date date) {
if (this instanceof WheelYearPicker) {
WheelYearPicker yearPick = (WheelYearPicker) this;
Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(dateHelper.getTimeZone());
calendar.setTime(date);
return calendar.get(Calendar.YEAR) - yearPick.minYear;
}
@@ -972,8 +1022,15 @@ public int findIndexOfDate(@NonNull Date date) {
return index;
}
+ public String getLocalizedString(@StringRes int stringRes) {
+ return LocaleHelper.getString(getContext(), getCurrentLocale(), stringRes);
+ }
+
@TargetApi(Build.VERSION_CODES.N)
public Locale getCurrentLocale() {
+ if (customLocale != null) {
+ return customLocale;
+ }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return getResources().getConfiguration().getLocales().get(0);
} else {
@@ -982,6 +1039,22 @@ public Locale getCurrentLocale() {
}
}
+ public void setDateHelper(DateHelper dateHelper) {
+ this.dateHelper = dateHelper;
+ }
+
+ public DateHelper getDateHelper() {
+ return dateHelper;
+ }
+
+ public void setShowOnlyFutureDate(boolean showOnlyFutureDate) {
+ this.showOnlyFutureDate = showOnlyFutureDate;
+ }
+
+ public boolean getShowOnlyFutureDate() {
+ return showOnlyFutureDate;
+ }
+
public interface BaseAdapter {
int getItemCount();
@@ -1068,12 +1141,16 @@ public int getItemCount() {
@Override
public V getItem(int position) {
final int itemCount = getItemCount();
- return itemCount != 0 ? data.get((position + itemCount) % itemCount) : null;
+ return itemCount == 0 ? null : data.get((position + itemCount) % itemCount);
}
@Override
public String getItemText(int position) {
- return String.valueOf(data.get(position));
+ try {
+ return String.valueOf(data.get(position));
+ } catch (Throwable t) {
+ return "";
+ }
}
public List getData() {
diff --git a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelYearPicker.java b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelYearPicker.java
index 77f20501..7412e8b2 100644
--- a/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelYearPicker.java
+++ b/singledateandtimepicker/src/main/java/com/github/florent37/singledateandtimepicker/widget/WheelYearPicker.java
@@ -2,7 +2,6 @@
import android.content.Context;
-import android.support.annotation.NonNull;
import android.util.AttributeSet;
import com.github.florent37.singledateandtimepicker.R;
@@ -12,6 +11,8 @@
import java.util.Calendar;
import java.util.List;
+import androidx.annotation.NonNull;
+
public class WheelYearPicker extends WheelPicker {
private SimpleDateFormat simpleDateFormat;
@@ -30,9 +31,10 @@ public WheelYearPicker(Context context, AttributeSet attrs) {
@Override
protected void init() {
- simpleDateFormat = new SimpleDateFormat("YYYY", getCurrentLocale());
+ simpleDateFormat = new SimpleDateFormat("yyyy", getCurrentLocale());
Calendar instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
int currentYear = instance.get(Calendar.YEAR);
this.minYear = currentYear - SingleDateAndTimeConstants.MIN_YEAR_DIFF;
this.maxYear = currentYear + SingleDateAndTimeConstants.MAX_YEAR_DIFF;
@@ -45,7 +47,7 @@ protected String initDefault() {
@NonNull
private String getTodayText() {
- return getResources().getString(R.string.picker_today);
+ return getLocalizedString(R.string.picker_today);
}
@Override
@@ -67,10 +69,11 @@ public void setMinYear(int minYear) {
}
@Override
- protected List generateAdapterValues() {
+ protected List generateAdapterValues(boolean showOnlyFutureDates) {
final List years = new ArrayList<>();
final Calendar instance = Calendar.getInstance();
+ instance.setTimeZone(dateHelper.getTimeZone());
instance.set(Calendar.YEAR, minYear-1);
for (int i = minYear; i <= maxYear; i++) {
@@ -100,4 +103,4 @@ private int convertItemToYear(int itemPosition) {
public interface OnYearSelectedListener {
void onYearSelected(WheelYearPicker picker, int position, int year);
}
-}
\ No newline at end of file
+}
diff --git a/singledateandtimepicker/src/main/res/drawable/picker_divider.xml b/singledateandtimepicker/src/main/res/drawable/picker_divider.xml
new file mode 100644
index 00000000..0c5c6f29
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/drawable/picker_divider.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/res/layout/single_day_picker.xml b/singledateandtimepicker/src/main/res/layout/single_day_and_time_picker.xml
similarity index 65%
rename from singledateandtimepicker/src/main/res/layout/single_day_picker.xml
rename to singledateandtimepicker/src/main/res/layout/single_day_and_time_picker.xml
index edd4f590..abbc8fab 100644
--- a/singledateandtimepicker/src/main/res/layout/single_day_picker.xml
+++ b/singledateandtimepicker/src/main/res/layout/single_day_and_time_picker.xml
@@ -1,84 +1,76 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="horizontal">
+ android:orientation="horizontal">
+ app:wheel_item_align="right" />
-
+ app:wheel_item_align="right" />
-
+ app:wheel_item_align="right" />
-
+ app:wheel_item_align="right"
+ android:layout_marginLeft="5dp"
+ android:layout_marginRight="5dp"/>
-
+ app:wheel_item_align="center" />
-
+ app:wheel_item_align="center" />
-
+ app:wheel_item_align="center"
+ app:wheel_visible_item_count="2" />
@@ -88,6 +80,26 @@
android:layout_height="@dimen/wheelSelectorHeight"
android:layout_gravity="center_vertical"
android:alpha="0.2"
- android:background="@color/picker_default_selector_color"/>
+ android:background="@color/picker_default_selector_color" />
+
+
+
+
-
\ No newline at end of file
+
+
+
diff --git a/singledateandtimepicker/src/main/res/values-ca/strings.xml b/singledateandtimepicker/src/main/res/values-ca/strings.xml
new file mode 100644
index 00000000..670ec337
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-ca/strings.xml
@@ -0,0 +1,4 @@
+
+
+ avui
+
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/res/values-es/strings.xml b/singledateandtimepicker/src/main/res/values-es/strings.xml
index e908e8d0..801faade 100644
--- a/singledateandtimepicker/src/main/res/values-es/strings.xml
+++ b/singledateandtimepicker/src/main/res/values-es/strings.xml
@@ -1,6 +1,4 @@
hoy
- PM
- A.M
diff --git a/singledateandtimepicker/src/main/res/values-fi/strings.xml b/singledateandtimepicker/src/main/res/values-fi/strings.xml
new file mode 100644
index 00000000..428b9f59
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-fi/strings.xml
@@ -0,0 +1,4 @@
+
+
+ tänään
+
diff --git a/singledateandtimepicker/src/main/values-id/strings.xml b/singledateandtimepicker/src/main/res/values-id/strings.xml
similarity index 100%
rename from singledateandtimepicker/src/main/values-id/strings.xml
rename to singledateandtimepicker/src/main/res/values-id/strings.xml
diff --git a/singledateandtimepicker/src/main/res/values-ko/strings.xml b/singledateandtimepicker/src/main/res/values-ko/strings.xml
new file mode 100644
index 00000000..fc3d4fe3
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-ko/strings.xml
@@ -0,0 +1,6 @@
+
+
+ 오늘
+ 오전
+ 오후
+
diff --git a/singledateandtimepicker/src/main/res/values-nb/strings.xml b/singledateandtimepicker/src/main/res/values-nb/strings.xml
new file mode 100644
index 00000000..007aeafa
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-nb/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Idag
+
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/res/values-pt/strings.xml b/singledateandtimepicker/src/main/res/values-pt/strings.xml
new file mode 100644
index 00000000..49af5e0b
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-pt/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Hoje
+
diff --git a/singledateandtimepicker/src/main/res/values-sv/strings.xml b/singledateandtimepicker/src/main/res/values-sv/strings.xml
new file mode 100644
index 00000000..007aeafa
--- /dev/null
+++ b/singledateandtimepicker/src/main/res/values-sv/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Idag
+
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/res/values/attrs.xml b/singledateandtimepicker/src/main/res/values/attrs.xml
index a2d9f508..2085fef0 100644
--- a/singledateandtimepicker/src/main/res/values/attrs.xml
+++ b/singledateandtimepicker/src/main/res/values/attrs.xml
@@ -32,10 +32,12 @@
+
+
-
+
@@ -44,5 +46,16 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/singledateandtimepicker/src/main/res/values/colors.xml b/singledateandtimepicker/src/main/res/values/colors.xml
index daa597bc..e9404610 100644
--- a/singledateandtimepicker/src/main/res/values/colors.xml
+++ b/singledateandtimepicker/src/main/res/values/colors.xml
@@ -7,4 +7,7 @@
#999
@android:color/black
#646464
+ @android:color/transparent
+ 1dp
+ @drawable/picker_divider
\ No newline at end of file