Unbundle DatePicker
Bug: 18777272
Change-Id: I2be6e5db694e5bfe2487f9bb87101756248dbc0c
diff --git a/src/com/android/contacts/datepicker/DatePicker.java b/src/com/android/contacts/datepicker/DatePicker.java
index 1b3b807..c6708a1 100644
--- a/src/com/android/contacts/datepicker/DatePicker.java
+++ b/src/com/android/contacts/datepicker/DatePicker.java
@@ -16,13 +16,8 @@
package com.android.contacts.datepicker;
-// This is a fork of the standard Android DatePicker that additionally allows toggling the year
-// on/off. It uses some private API so that not everything has to be copied.
-
import android.animation.LayoutTransition;
-import android.annotation.Widget;
import android.content.Context;
-import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateFormat;
@@ -41,13 +36,13 @@
import com.android.contacts.R;
import java.text.DateFormatSymbols;
-import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
-import libcore.icu.ICU;
-
/**
+ * This is a fork of the standard Android DatePicker that additionally allows toggling the year
+ * on/off.
+ *
* A view for selecting a month / year / day based on a calendar like layout.
*
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
@@ -55,13 +50,13 @@
*
* For a dialog using this view, see {@link android.app.DatePickerDialog}.
*/
-@Widget
public class DatePicker extends FrameLayout {
/** Magic year that represents "no year" */
public static int NO_YEAR = 0;
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
+ private static final TwoDigitFormatter sTwoDigitFormatter = new TwoDigitFormatter();
/* UI Components */
private final LinearLayout mPickerContainer;
@@ -113,7 +108,7 @@
mPickerContainer = (LinearLayout) findViewById(R.id.parent);
mDayPicker = (NumberPicker) findViewById(R.id.day);
- mDayPicker.setFormatter(NumberPicker.getTwoDigitFormatter());
+ mDayPicker.setFormatter(sTwoDigitFormatter);
mDayPicker.setOnLongPressUpdateInterval(100);
mDayPicker.setOnValueChangedListener(new OnValueChangeListener() {
@Override
@@ -123,7 +118,7 @@
}
});
mMonthPicker = (NumberPicker) findViewById(R.id.month);
- mMonthPicker.setFormatter(NumberPicker.getTwoDigitFormatter());
+ mMonthPicker.setFormatter(sTwoDigitFormatter);
DateFormatSymbols dfs = new DateFormatSymbols();
String[] months = dfs.getShortMonths();
diff --git a/src/com/android/contacts/datepicker/ICU.java b/src/com/android/contacts/datepicker/ICU.java
new file mode 100644
index 0000000..229fda6
--- /dev/null
+++ b/src/com/android/contacts/datepicker/ICU.java
@@ -0,0 +1,51 @@
+package com.android.contacts.datepicker;
+
+public class ICU {
+
+ /**
+ * This method is directly copied from {@link libcore.icu.ICU}. The method is simple enough
+ * that it probably won't change.
+ */
+ public static char[] getDateFormatOrder(String pattern) {
+ char[] result = new char[3];
+ int resultIndex = 0;
+ boolean sawDay = false;
+ boolean sawMonth = false;
+ boolean sawYear = false;
+
+ for (int i = 0; i < pattern.length(); ++i) {
+ char ch = pattern.charAt(i);
+ if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') {
+ if (ch == 'd' && !sawDay) {
+ result[resultIndex++] = 'd';
+ sawDay = true;
+ } else if ((ch == 'L' || ch == 'M') && !sawMonth) {
+ result[resultIndex++] = 'M';
+ sawMonth = true;
+ } else if ((ch == 'y') && !sawYear) {
+ result[resultIndex++] = 'y';
+ sawYear = true;
+ }
+ } else if (ch == 'G') {
+ // Ignore the era specifier, if present.
+ } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
+ throw new IllegalArgumentException("Bad pattern character '"
+ + ch + "' in " + pattern);
+ } else if (ch == '\'') {
+ if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') {
+ ++i;
+ } else {
+ i = pattern.indexOf('\'', i + 1);
+ if (i == -1) {
+ throw new IllegalArgumentException("Bad quoting in " + pattern);
+ }
+ ++i;
+ }
+ } else {
+ // Ignore spaces and punctuation.
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/src/com/android/contacts/datepicker/TwoDigitFormatter.java b/src/com/android/contacts/datepicker/TwoDigitFormatter.java
new file mode 100644
index 0000000..7e03f28
--- /dev/null
+++ b/src/com/android/contacts/datepicker/TwoDigitFormatter.java
@@ -0,0 +1,55 @@
+package com.android.contacts.datepicker;
+
+import android.widget.NumberPicker;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+/**
+ * Copy of {@link android.widget.NumberPicker.TwoDigitFormatter}, modified
+ * so that it doesn't use libcore.
+ *
+ * Use a custom NumberPicker formatting callback to use two-digit minutes
+ * strings like "01". Keeping a static formatter etc. is the most efficient
+ * way to do this; it avoids creating temporary objects on every call to
+ * format().
+ */
+public class TwoDigitFormatter implements NumberPicker.Formatter {
+ final StringBuilder mBuilder = new StringBuilder();
+
+ char mZeroDigit;
+ java.util.Formatter mFmt;
+
+ final Object[] mArgs = new Object[1];
+
+ public TwoDigitFormatter() {
+ final Locale locale = Locale.getDefault();
+ init(locale);
+ }
+
+ private void init(Locale locale) {
+ mFmt = createFormatter(locale);
+ mZeroDigit = getZeroDigit(locale);
+ }
+
+ public String format(int value) {
+ final Locale currentLocale = Locale.getDefault();
+ if (mZeroDigit != getZeroDigit(currentLocale)) {
+ init(currentLocale);
+ }
+ mArgs[0] = value;
+ mBuilder.delete(0, mBuilder.length());
+ mFmt.format("%02d", mArgs);
+ return mFmt.toString();
+ }
+
+ private static char getZeroDigit(Locale locale) {
+ // The original TwoDigitFormatter directly referenced LocaleData's value. Instead,
+ // we need to use the public DecimalFormatSymbols API.
+ return DecimalFormatSymbols.getInstance(locale).getZeroDigit();
+ }
+
+ private java.util.Formatter createFormatter(Locale locale) {
+ return new java.util.Formatter(mBuilder, locale);
+ }
+}