summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Kung <kingkung@google.com>2013-04-10 17:37:26 -0700
committerJames Kung <kingkung@google.com>2013-04-10 19:25:39 -0700
commit2e00aa34c051111529290cf23c6ba940c2c0c142 (patch)
tree6fa588f28300d9bda10c7bc2cac16726b0b3103e
parent541b40d9c4cef3805b2eff91968669a1a9aa901a (diff)
downloadandroid_frameworks_opt_datetimepicker-2e00aa34c051111529290cf23c6ba940c2c0c142.tar.gz
android_frameworks_opt_datetimepicker-2e00aa34c051111529290cf23c6ba940c2c0c142.tar.bz2
android_frameworks_opt_datetimepicker-2e00aa34c051111529290cf23c6ba940c2c0c142.zip
Date picker layout modifications
Bug: 8581974 Change-Id: I3c547c2ebf1bb6488b823044bd7fd7bdffdab69e
-rw-r--r--res/color/date_picker_selector.xml6
-rw-r--r--res/color/date_picker_year_selector.xml22
-rw-r--r--res/layout/date_picker_done_button.xml3
-rw-r--r--res/layout/year_label_text_view.xml (renamed from res/layout/month_text_view.xml)9
-rw-r--r--res/values-v16/strings.xml2
-rw-r--r--res/values-v16/styles.xml4
-rw-r--r--res/values/colors.xml26
-rw-r--r--res/values/dimens.xml6
-rw-r--r--res/values/strings.xml2
-rw-r--r--res/values/styles.xml2
-rw-r--r--src/com/android/datetimepicker/Utils.java9
-rw-r--r--src/com/android/datetimepicker/date/DatePickerController.java21
-rw-r--r--src/com/android/datetimepicker/date/DatePickerDialog.java156
-rw-r--r--src/com/android/datetimepicker/date/DayPickerView.java146
-rw-r--r--src/com/android/datetimepicker/date/MonthPickerView.java94
-rw-r--r--src/com/android/datetimepicker/date/OnDateChangedListener.java0
-rw-r--r--src/com/android/datetimepicker/date/SimpleMonthAdapter.java3
-rw-r--r--src/com/android/datetimepicker/date/SimpleMonthView.java50
-rw-r--r--src/com/android/datetimepicker/date/TextViewWithCircularIndicator.java (renamed from src/com/android/datetimepicker/date/SelectableTextView.java)23
-rw-r--r--src/com/android/datetimepicker/date/YearPickerView.java133
-rw-r--r--src/com/android/datetimepicker/time/TimePickerDialog.java5
21 files changed, 382 insertions, 340 deletions
diff --git a/res/color/date_picker_selector.xml b/res/color/date_picker_selector.xml
index 0d373eb..63e1e17 100644
--- a/res/color/date_picker_selector.xml
+++ b/res/color/date_picker_selector.xml
@@ -15,9 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:color="@color/selected_text"/>
- <item android:state_selected="true" android:color="@color/selected_text"/>
+ <item android:state_pressed="true" android:color="@color/darker_blue"/>
+ <item android:state_pressed="false" android:state_selected="true" android:color="@color/blue"/>
<item android:state_pressed="false" android:state_selected="false"
- android:color="@color/calendar_selected_date_text"/>
+ android:color="@color/date_picker_text_normal"/>
</selector> \ No newline at end of file
diff --git a/res/color/date_picker_year_selector.xml b/res/color/date_picker_year_selector.xml
new file mode 100644
index 0000000..f5cf776
--- /dev/null
+++ b/res/color/date_picker_year_selector.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_pressed="true" android:color="@color/darker_blue"/>
+ <item android:state_pressed="false" android:state_selected="false"
+ android:color="@color/date_picker_text_normal"/>
+
+</selector> \ No newline at end of file
diff --git a/res/layout/date_picker_done_button.xml b/res/layout/date_picker_done_button.xml
index 8d61f4b..4556f7a 100644
--- a/res/layout/date_picker_done_button.xml
+++ b/res/layout/date_picker_done_button.xml
@@ -25,5 +25,6 @@
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/done_label" />
+ android:text="@string/done_label"
+ android:textColor="@color/done_text_color" />
</LinearLayout>
diff --git a/res/layout/month_text_view.xml b/res/layout/year_label_text_view.xml
index df2bfde..33d6b25 100644
--- a/res/layout/month_text_view.xml
+++ b/res/layout/year_label_text_view.xml
@@ -13,13 +13,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.datetimepicker.date.SelectableTextView
+<com.android.datetimepicker.date.TextViewWithCircularIndicator
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/month_text_view"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/year_label_height"
android:layout_gravity="center"
android:gravity="center"
- android:padding="@dimen/month_list_item_padding"
- android:textColor="@color/calendar_day_number"
- android:textSize="@dimen/month_list_item_size" />
+ android:textColor="@color/date_picker_year_selector"
+ android:textSize="@dimen/year_label_text_size" />
diff --git a/res/values-v16/strings.xml b/res/values-v16/strings.xml
index 5875d80..9c24262 100644
--- a/res/values-v16/strings.xml
+++ b/res/values-v16/strings.xml
@@ -17,4 +17,6 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- DO NOT TRANSLATE -->
<string name="radial_numbers_typeface">sans-serif-light</string>
+ <!-- DO NOT TRANSLATE -->
+ <string name="day_of_week_label_typeface">sans-serif-light</string>
</resources>
diff --git a/res/values-v16/styles.xml b/res/values-v16/styles.xml
index 88ee2a2..a6f21dc 100644
--- a/res/values-v16/styles.xml
+++ b/res/values-v16/styles.xml
@@ -23,4 +23,8 @@
<style name="done_button_light">
<item name="android:fontFamily">sans-serif-light</item>
</style>
+
+ <style name="day_of_week_label_condensed">
+ <item name="android:fontFamily">sans-serif-condensed</item>
+ </style>
</resources> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 506d640..2672bfa 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -25,33 +25,11 @@
<color name="transparent_black">#7F000000</color>
<color name="blue">#33b5e5</color>
+ <color name="darker_blue">#0099CC</color>
+ <color name="date_picker_text_normal">#FF999999</color>
<color name="calendar_header">#999999</color>
- <color name="calendar_week_labels">#FFDBDCDE</color>
<color name="calendar_pager">#FFECEDEE</color>
- <color name="calendar_day_number">#FF999999</color>
<color name="calendar_selected_date_text">#FFD1D2D4</color>
<color name="done_button_color">#FFECEDEE</color>
- <color name="selected_text">#FF33B5E5</color>
- <color name="mini_month_bg_color">#FFFFFFFF</color>
- <color name="mini_month_today_outline_color">#FF000000</color>
- <color name="month_day_number">#999999</color>
- <color name="month_mini_day_number">#FF000000</color>
- <color name="month_day_number_other">#FF999999</color>
- <color name="month_week_num_color">#FF999999</color>
- <color name="month_day_names_color">#FF999999</color>
- <color name="month_today_number">#FF333333</color>
- <color name="month_event_color">#FF333333</color>
- <color name="month_event_extra_color">#FF666666</color>
- <color name="month_event_other_color">#FF666666</color>
- <color name="month_event_extra_other_color">#4C999999</color>
- <color name="month_saturday">#80333333</color>
- <color name="month_sunday">#80333333</color>
- <color name="month_grid_lines">#ffCCCCCC</color>
- <color name="month_other_month_day_number">#ff939497</color>
- <color name="month_other_bgcolor">#FFEEEEEE</color>
- <color name="month_selected_week_bgcolor">#FFDDDDDD</color>
- <color name="month_today_bgcolor">#FFFFFFFF</color>
- <color name="month_bgcolor">#FFE5E5E5</color>
-
</resources> \ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 691ab0f..5ebc099 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -48,15 +48,15 @@
<dimen name="done_button_height">42dp</dimen>
<dimen name="date_picker_header_height">30dp</dimen>
<dimen name="month_list_item_header_height">50dp</dimen>
- <dimen name="month_list_item_padding">16dp</dimen>
<dimen name="month_day_label_text_size">10sp</dimen>
<dimen name="day_number_select_circle_radius">16dp</dimen>
- <dimen name="month_select_circle_radius">24dp</dimen>
+ <dimen name="month_select_circle_radius">45dp</dimen>
<dimen name="selected_date_year_size">30dp</dimen>
<dimen name="selected_date_day_size">75dp</dimen>
<dimen name="selected_date_month_size">30dp</dimen>
<dimen name="date_picker_header_text_size">14dp</dimen>
<dimen name="month_label_size">16sp</dimen>
<dimen name="day_number_size">16sp</dimen>
- <dimen name="month_list_item_size">16sp</dimen>
+ <dimen name="year_label_height">64dp</dimen>
+ <dimen name="year_label_text_size">22dp</dimen>
</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3129b0d..ada4db0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -45,4 +45,6 @@
<!-- DO NOT TRANSLATE -->
<string name="sans_serif">sans-serif</string>
+ <!-- DO NOT TRANSLATE -->
+ <string name="day_of_week_label_typeface">sans-serif</string>
</resources> \ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 32ac1b9..af53509 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -47,4 +47,6 @@
<item name="android:textAllCaps">true</item>
<item name="android:textColor">@color/ampm_text_color</item>
</style>
+
+ <style name="day_of_week_label_condensed" />
</resources> \ No newline at end of file
diff --git a/src/com/android/datetimepicker/Utils.java b/src/com/android/datetimepicker/Utils.java
index ae3087b..83590bf 100644
--- a/src/com/android/datetimepicker/Utils.java
+++ b/src/com/android/datetimepicker/Utils.java
@@ -31,7 +31,7 @@ import java.util.Calendar;
public class Utils {
public static final int MONDAY_BEFORE_JULIAN_EPOCH = Time.EPOCH_JULIAN_DAY - 3;
- public static final int PULSE_ANIMATOR_DURATION = 600;
+ public static final int PULSE_ANIMATOR_DURATION = 544;
static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
@@ -103,10 +103,11 @@ public class Utils {
* @param labelToAnimate the view to pulsate.
* @return The animator object. Use .start() to begin.
*/
- public static ObjectAnimator getPulseAnimator(View labelToAnimate) {
+ public static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio,
+ float increaseRatio) {
Keyframe k0 = Keyframe.ofFloat(0f, 1f);
- Keyframe k1 = Keyframe.ofFloat(0.25f, 0.85f);
- Keyframe k2 = Keyframe.ofFloat(0.625f, 1.1f);
+ Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio);
+ Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
Keyframe k3 = Keyframe.ofFloat(1f, 1f);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3);
diff --git a/src/com/android/datetimepicker/date/DatePickerController.java b/src/com/android/datetimepicker/date/DatePickerController.java
index f92d687..173e58a 100644
--- a/src/com/android/datetimepicker/date/DatePickerController.java
+++ b/src/com/android/datetimepicker/date/DatePickerController.java
@@ -16,24 +16,29 @@
package com.android.datetimepicker.date;
+import com.android.datetimepicker.date.DatePickerDialog.OnDateChangedListener;
import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
/**
* Controller class to communicate among the various components of the date picker dialog.
*/
-public interface DatePickerController {
+interface DatePickerController {
- public void onYearPickerSelectionChanged(int year);
+ void onYearSelected(int year);
- public void onMonthPickerSelectionChanged(int month);
+ void onDayOfMonthSelected(int year, int month, int day);
- public void onDayPickerSelectionChanged(int year, int month, int day);
+ void registerOnDateChangedListener(OnDateChangedListener listener);
- public CalendarDay getSelectedDay();
+ void unregisterOnDateChangedListener(OnDateChangedListener listener);
- public int getFirstDayOfWeek();
+ CalendarDay getSelectedDay();
- public int getMinYear();
+ int getFirstDayOfWeek();
- public int getMaxYear();
+ int getMinYear();
+
+ int getMaxYear();
+
+ void tryVibrate();
}
diff --git a/src/com/android/datetimepicker/date/DatePickerDialog.java b/src/com/android/datetimepicker/date/DatePickerDialog.java
index e2b91ad..77bedbf 100644
--- a/src/com/android/datetimepicker/date/DatePickerDialog.java
+++ b/src/com/android/datetimepicker/date/DatePickerDialog.java
@@ -16,9 +16,13 @@
package com.android.datetimepicker.date;
+import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.DialogFragment;
+import android.content.Context;
import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.Vibrator;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,6 +43,8 @@ import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Locale;
/**
@@ -49,15 +55,14 @@ public class DatePickerDialog extends DialogFragment implements
private static final String TAG = "DatePickerDialog";
- private static final int TOTAL_VIEWS = 2;
-
+ private static final int UNINITIALIZED = -1;
private static final int MONTH_AND_DAY_VIEW = 0;
private static final int YEAR_VIEW = 1;
private static final String KEY_SELECTED_YEAR = "year";
private static final String KEY_SELECTED_MONTH = "month";
private static final String KEY_SELECTED_DAY = "day";
- private static final String KEY_LIST_POSITION = "position";
+ private static final String KEY_LIST_POSITION = "list_position";
private static final String KEY_WEEK_START = "week_start";
private static final String KEY_YEAR_START = "year_start";
private static final String KEY_YEAR_END = "year_end";
@@ -66,13 +71,15 @@ public class DatePickerDialog extends DialogFragment implements
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
- private static final int ANIMATION_DURATION = 500;
+ private static final int ANIMATION_DURATION = 300;
+ private static final int ANIMATION_DELAY = 500;
private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy", Locale.getDefault());
private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd", Locale.getDefault());
private final Calendar mCalendar = Calendar.getInstance();
private OnDateSetListener mCallBack;
+ private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
private ViewAnimator mAnimator;
@@ -85,13 +92,16 @@ public class DatePickerDialog extends DialogFragment implements
private YearPickerView mYearPickerView;
private Button mDoneButton;
- private int mCurrentView;
+ private int mCurrentView = UNINITIALIZED;
private int mWeekStart = mCalendar.getFirstDayOfWeek();
private int mMinYear = DEFAULT_START_YEAR;
private int mMaxYear = DEFAULT_END_YEAR;
- private final View[] mViews = new View[TOTAL_VIEWS];
+ private Vibrator mVibrator;
+ private long mLastVibrate;
+
+ private boolean mDelayAnimation = true;
/**
* The callback used to indicate the user is done filling in the date.
@@ -108,6 +118,15 @@ public class DatePickerDialog extends DialogFragment implements
void onDateSet(DatePickerDialog dialog, int year, int monthOfYear, int dayOfMonth);
}
+ /**
+ * The callback used to notify other date picker components of a change in selected date.
+ */
+ interface OnDateChangedListener {
+
+ public void onDateChanged();
+ }
+
+
public DatePickerDialog() {
// Empty constructor required for dialog fragment.
}
@@ -136,8 +155,10 @@ public class DatePickerDialog extends DialogFragment implements
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getActivity().getWindow().setSoftInputMode(
+ final Activity activity = getActivity();
+ activity.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+ mVibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
if (savedInstanceState != null) {
mCalendar.set(Calendar.YEAR, savedInstanceState.getInt(KEY_SELECTED_YEAR));
mCalendar.set(Calendar.MONTH, savedInstanceState.getInt(KEY_SELECTED_MONTH));
@@ -151,11 +172,17 @@ public class DatePickerDialog extends DialogFragment implements
outState.putInt(KEY_SELECTED_YEAR, mCalendar.get(Calendar.YEAR));
outState.putInt(KEY_SELECTED_MONTH, mCalendar.get(Calendar.MONTH));
outState.putInt(KEY_SELECTED_DAY, mCalendar.get(Calendar.DAY_OF_MONTH));
- outState.putInt(KEY_LIST_POSITION, mDayPickerView.getFirstVisiblePosition());
outState.putInt(KEY_WEEK_START, mWeekStart);
outState.putInt(KEY_YEAR_START, mMinYear);
outState.putInt(KEY_YEAR_END, mMaxYear);
outState.putInt(KEY_CURRENT_VIEW, mCurrentView);
+ int listPosition = -1;
+ if (mCurrentView == MONTH_AND_DAY_VIEW) {
+ listPosition = mDayPickerView.getMostVisiblePosition();
+ } else if (mCurrentView == YEAR_VIEW) {
+ listPosition = mYearPickerView.getFirstVisiblePosition();
+ }
+ outState.putInt(KEY_LIST_POSITION, listPosition);
}
@Override
@@ -173,27 +200,24 @@ public class DatePickerDialog extends DialogFragment implements
mSelectedDayTextView = (TextView) view.findViewById(R.id.date_picker_day);
mYearView = (TextView) view.findViewById(R.id.date_picker_year);
mYearView.setOnClickListener(this);
- final Activity activity = getActivity();
+ int listPosition = -1;
int currentView = MONTH_AND_DAY_VIEW;
- mDayPickerView = new DayPickerView(activity, this);
if (savedInstanceState != null) {
- Log.d(TAG,
- "Setting first visible position: "
- + savedInstanceState.getInt(KEY_LIST_POSITION));
- mDayPickerView.setSelectionFromTop(savedInstanceState.getInt(KEY_LIST_POSITION),
- DayPickerView.LIST_TOP_OFFSET);
mWeekStart = savedInstanceState.getInt(KEY_WEEK_START);
mMinYear = savedInstanceState.getInt(KEY_YEAR_START);
mMaxYear = savedInstanceState.getInt(KEY_YEAR_END);
currentView = savedInstanceState.getInt(KEY_CURRENT_VIEW);
+ listPosition = savedInstanceState.getInt(KEY_LIST_POSITION);
}
- mYearPickerView = new YearPickerView(activity, this);
- mViews[MONTH_AND_DAY_VIEW] = mDayPickerView;
- mViews[YEAR_VIEW] = mYearPickerView;
+ final Activity activity = getActivity();
+ mDayPickerView = new DayPickerView(activity, this);
+ mYearPickerView = new YearPickerView(activity, this);
mAnimator = (ViewAnimator) view.findViewById(R.id.animator);
+ mAnimator.addView(mDayPickerView);
+ mAnimator.addView(mYearPickerView);
// TODO: Replace with animation decided upon by the design team.
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(ANIMATION_DURATION);
@@ -202,14 +226,13 @@ public class DatePickerDialog extends DialogFragment implements
Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
animation2.setDuration(ANIMATION_DURATION);
mAnimator.setOutAnimation(animation2);
- mAnimator.addView(mDayPickerView);
- mAnimator.addView(mYearPickerView);
mDoneButton = (Button) view.findViewById(R.id.done);
mDoneButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
+ tryVibrate();
if (mCallBack != null) {
mCallBack.onDateSet(DatePickerDialog.this, mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
@@ -221,22 +244,48 @@ public class DatePickerDialog extends DialogFragment implements
updateDisplay();
setCurrentView(currentView);
+ if (listPosition != -1) {
+ if (currentView == MONTH_AND_DAY_VIEW) {
+ mDayPickerView.postSetSelection(listPosition);
+ } else if (currentView == YEAR_VIEW) {
+ mYearPickerView.postSetSelection(listPosition);
+ }
+ }
return view;
}
private void setCurrentView(final int viewIndex) {
switch (viewIndex) {
case MONTH_AND_DAY_VIEW:
- mCurrentView = viewIndex;
- mMonthAndDayView.setSelected(true);
- mYearView.setSelected(false);
- mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
+ ObjectAnimator pulseAnimator = Utils.getPulseAnimator(mMonthAndDayView, 0.9f,
+ 1.05f);
+ if (mDelayAnimation) {
+ pulseAnimator.setStartDelay(ANIMATION_DELAY);
+ mDelayAnimation = false;
+ }
+ mDayPickerView.onDateChanged();
+ if (mCurrentView != viewIndex) {
+ mMonthAndDayView.setSelected(true);
+ mYearView.setSelected(false);
+ mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
+ mCurrentView = viewIndex;
+ }
+ pulseAnimator.start();
break;
case YEAR_VIEW:
- mCurrentView = viewIndex;
- mMonthAndDayView.setSelected(false);
- mYearView.setSelected(true);
- mAnimator.setDisplayedChild(YEAR_VIEW);
+ pulseAnimator = Utils.getPulseAnimator(mYearView, 0.85f, 1.1f);
+ if (mDelayAnimation) {
+ pulseAnimator.setStartDelay(ANIMATION_DELAY);
+ mDelayAnimation = false;
+ }
+ mYearPickerView.onDateChanged();
+ if (mCurrentView != viewIndex) {
+ mMonthAndDayView.setSelected(false);
+ mYearView.setSelected(true);
+ mAnimator.setDisplayedChild(YEAR_VIEW);
+ mCurrentView = viewIndex;
+ }
+ pulseAnimator.start();
break;
}
}
@@ -271,7 +320,6 @@ public class DatePickerDialog extends DialogFragment implements
mMaxYear = endYear;
if (mDayPickerView != null) {
mDayPickerView.onChange();
- mYearPickerView.onChange();
}
}
@@ -293,6 +341,7 @@ public class DatePickerDialog extends DialogFragment implements
@Override
public void onClick(View v) {
+ tryVibrate();
if (v.getId() == R.id.date_picker_year) {
setCurrentView(YEAR_VIEW);
} else if (v.getId() == R.id.date_picker_month_and_day) {
@@ -301,31 +350,30 @@ public class DatePickerDialog extends DialogFragment implements
}
@Override
- public void onYearPickerSelectionChanged(int year) {
+ public void onYearSelected(int year) {
adjustDayInMonthIfNeeded(mCalendar.get(Calendar.MONTH), year);
mCalendar.set(Calendar.YEAR, year);
- mDayPickerView.setCalendarDate(getSelectedDay());
- updateDisplay();
- }
-
- @Override
- public void onMonthPickerSelectionChanged(int month) {
- adjustDayInMonthIfNeeded(month, mCalendar.get(Calendar.YEAR));
- mCalendar.set(Calendar.MONTH, month);
- mDayPickerView.setCalendarDate(getSelectedDay());
+ updatePickers();
setCurrentView(MONTH_AND_DAY_VIEW);
updateDisplay();
}
@Override
- public void onDayPickerSelectionChanged(int year, int month, int day) {
+ public void onDayOfMonthSelected(int year, int month, int day) {
mCalendar.set(Calendar.YEAR, year);
mCalendar.set(Calendar.MONTH, month);
mCalendar.set(Calendar.DAY_OF_MONTH, day);
- mYearPickerView.setValue(mCalendar.get(Calendar.YEAR));
+ updatePickers();
updateDisplay();
}
+ private void updatePickers() {
+ Iterator<OnDateChangedListener> iterator = mListeners.iterator();
+ while (iterator.hasNext()) {
+ iterator.next().onDateChanged();
+ }
+ }
+
@Override
public CalendarDay getSelectedDay() {
@@ -346,4 +394,30 @@ public class DatePickerDialog extends DialogFragment implements
public int getFirstDayOfWeek() {
return mWeekStart;
}
+
+ @Override
+ public void registerOnDateChangedListener(OnDateChangedListener listener) {
+ mListeners.add(listener);
+ }
+
+ @Override
+ public void unregisterOnDateChangedListener(OnDateChangedListener listener) {
+ mListeners.remove(listener);
+ }
+
+ /**
+ * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
+ * happen if we have vibrated very recently.
+ */
+ @Override
+ public void tryVibrate() {
+ if (mVibrator != null) {
+ long now = SystemClock.uptimeMillis();
+ // We want to try to vibrate each individual tick discretely.
+ if (now - mLastVibrate >= 125) {
+ mVibrator.vibrate(5);
+ mLastVibrate = now;
+ }
+ }
+ }
}
diff --git a/src/com/android/datetimepicker/date/DayPickerView.java b/src/com/android/datetimepicker/date/DayPickerView.java
index 76dcf4f..1b0e871 100644
--- a/src/com/android/datetimepicker/date/DayPickerView.java
+++ b/src/com/android/datetimepicker/date/DayPickerView.java
@@ -17,9 +17,7 @@
package com.android.datetimepicker.date;
import android.content.Context;
-import android.database.DataSetObserver;
import android.os.Handler;
-import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.view.ViewConfiguration;
@@ -27,15 +25,13 @@ import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
+import com.android.datetimepicker.date.DatePickerDialog.OnDateChangedListener;
import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
-import java.util.Calendar;
-import java.util.Locale;
-
/**
* This displays a list of months in a calendar format with selectable days.
*/
-public class DayPickerView extends ListView implements OnScrollListener {
+public class DayPickerView extends ListView implements OnScrollListener, OnDateChangedListener {
private static final String TAG = "MonthFragment";
@@ -61,8 +57,6 @@ public class DayPickerView extends ListView implements OnScrollListener {
protected Context mContext;
protected Handler mHandler;
- protected float mMinimumFlingVelocity;
-
// highlighted time
protected CalendarDay mSelectedDay = new CalendarDay();
protected SimpleMonthAdapter mAdapter;
@@ -72,8 +66,6 @@ public class DayPickerView extends ListView implements OnScrollListener {
private static float mScale = 0;
// When the week starts; numbered like Time.<WEEKDAY> (e.g. SUNDAY=0).
protected int mFirstDayOfWeek;
- // The first day that is visible in the view
- protected Time mFirstVisibleDay = new Time();
// The last name announced by accessibility
protected CharSequence mPrevMonthName;
// which month should be displayed/highlighted [0-11]
@@ -87,61 +79,19 @@ public class DayPickerView extends ListView implements OnScrollListener {
private final DatePickerController mController;
- // This causes an update of the view at midnight
- protected Runnable mTodayUpdater = new Runnable() {
- @Override
- public void run() {
- Time midnight = new Time(mFirstVisibleDay.timezone);
- midnight.setToNow();
- long currentMillis = midnight.toMillis(true);
-
- midnight.hour = 0;
- midnight.minute = 0;
- midnight.second = 0;
- midnight.monthDay++;
- long millisToMidnight = midnight.normalize(true) - currentMillis;
- mHandler.postDelayed(this, millisToMidnight);
-
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
- }
- };
-
- // This allows us to update our position when a day is tapped
- protected DataSetObserver mObserver = new DataSetObserver() {
- @Override
- public void onChanged() {
- CalendarDay day = mAdapter.getSelectedDay();
- if (day.year != mSelectedDay.year || day.day != mSelectedDay.day) {
- goTo(day, true, true, false);
- }
- }
- };
-
public DayPickerView(Context context, DatePickerController controller) {
super(context);
mHandler = new Handler();
mController = controller;
+ mController.registerOnDateChangedListener(this);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setDrawSelectorOnTop(false);
init(context);
- setCalendarDate(controller.getSelectedDay());
- }
-
- public void setCalendarDate(CalendarDay day) {
- goTo(day, false, true, true);
+ onDateChanged();
}
public void init(Context context) {
mContext = context;
- String tz = Time.getCurrentTimezone();
- ViewConfiguration viewConfig = ViewConfiguration.get(context);
- mMinimumFlingVelocity = viewConfig.getScaledMinimumFlingVelocity();
-
- mFirstVisibleDay.timezone = tz;
- mFirstVisibleDay.normalize(true);
-
setUpListView();
setUpAdapter();
setAdapter(mAdapter);
@@ -159,7 +109,6 @@ public class DayPickerView extends ListView implements OnScrollListener {
protected void setUpAdapter() {
if (mAdapter == null) {
mAdapter = new SimpleMonthAdapter(getContext(), mController);
- mAdapter.registerDataSetObserver(mObserver);
} else {
mAdapter.setSelectedDay(mSelectedDay);
mAdapter.notifyDataSetChanged();
@@ -188,41 +137,6 @@ public class DayPickerView extends ListView implements OnScrollListener {
setFriction(ViewConfiguration.getScrollFriction() * mFriction);
}
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- setUpAdapter();
- doResumeUpdates();
- }
-
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mHandler.removeCallbacks(mTodayUpdater);
- }
-
- // @Override
- // public void onSaveInstanceState(Bundle outState) {
- // outState.putLong(KEY_CURRENT_TIME, mSelectedDay.toMillis(true));
- // }
-
- /**
- * Updates the user preference fields. Override this to use a different
- * preference space.
- */
- protected void doResumeUpdates() {
- // Get default week start based on locale, subtracting one for use with
- // android Time.
- Calendar cal = Calendar.getInstance(Locale.getDefault());
- mFirstDayOfWeek = cal.getFirstDayOfWeek() - 1;
-
- mShowWeekNumber = false;
-
- goTo(mSelectedDay, false, false, false);
- mAdapter.setSelectedDay(mSelectedDay);
- mTodayUpdater.run();
- }
-
/**
* This moves to the specified time in the view. If the time is not already
* in range it will move the list so that the first of the month containing
@@ -246,10 +160,9 @@ public class DayPickerView extends ListView implements OnScrollListener {
}
mTempDay.set(day);
- // Get the week we're going to
- // TODO push Util function into Calendar public api.
- int position = (day.year - mController.getMinYear())
+ final int position = (day.year - mController.getMinYear())
* SimpleMonthAdapter.MONTHS_IN_YEAR + day.month;
+ Log.d(TAG, "Year: " + day.year);
View child;
int i = 0;
@@ -291,8 +204,7 @@ public class DayPickerView extends ListView implements OnScrollListener {
position, LIST_TOP_OFFSET, GOTO_SCROLL_DURATION);
return true;
} else {
- setSelectionFromTop(position, LIST_TOP_OFFSET);
- onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE);
+ postSetSelection(position);
}
} else if (setSelected) {
setMonthDisplayed(mSelectedDay);
@@ -300,6 +212,18 @@ public class DayPickerView extends ListView implements OnScrollListener {
return false;
}
+ public void postSetSelection(final int position) {
+ clearFocus();
+ post(new Runnable() {
+
+ @Override
+ public void run() {
+ setSelection(position);
+ }
+ });
+ onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE);
+ }
+
/**
* Updates the title and selected month if the view has moved to a new
* month.
@@ -391,4 +315,36 @@ public class DayPickerView extends ListView implements OnScrollListener {
}
}
}
+
+ /**
+ * Gets the position of the view that is most prominently displayed within the list view.
+ */
+ public int getMostVisiblePosition() {
+ final int firstPosition = getFirstVisiblePosition();
+ final int height = getHeight();
+
+ int maxDisplayedHeight = 0;
+ int mostVisibleIndex = 0;
+ int i=0;
+ int bottom = 0;
+ while (bottom < height) {
+ View child = getChildAt(i);
+ if (child == null) {
+ break;
+ }
+ bottom = child.getBottom();
+ int displayedHeight = Math.min(bottom, height) - Math.max(0, child.getTop());
+ if (displayedHeight > maxDisplayedHeight) {
+ mostVisibleIndex = i;
+ maxDisplayedHeight = displayedHeight;
+ }
+ i++;
+ }
+ return firstPosition + mostVisibleIndex;
+ }
+
+ @Override
+ public void onDateChanged() {
+ goTo(mController.getSelectedDay(), false, true, true);
+ }
}
diff --git a/src/com/android/datetimepicker/date/MonthPickerView.java b/src/com/android/datetimepicker/date/MonthPickerView.java
deleted file mode 100644
index 81f10ab..0000000
--- a/src/com/android/datetimepicker/date/MonthPickerView.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.datetimepicker.date;
-
-import android.content.Context;
-import android.graphics.drawable.StateListDrawable;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.GridView;
-import android.widget.SimpleAdapter;
-
-import com.android.datetimepicker.R;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Displays a selectable list of months in a grid format.
- */
-public class MonthPickerView extends GridView implements OnItemClickListener {
-
- private static final int NUM_COLUMNS = 3;
- private static final int NUM_MONTHS = 12;
-
- private final Calendar mCalendar = Calendar.getInstance();
- private final DatePickerController mController;
-
- /**
- * @param context
- */
- public MonthPickerView(Context context, DatePickerController controller) {
- super(context);
- ViewGroup.LayoutParams frame = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.WRAP_CONTENT);
- setLayoutParams(frame);
- setNumColumns(NUM_COLUMNS);
- init(context);
- mController = controller;
- setOnItemClickListener(this);
- setSelector(new StateListDrawable());
- }
-
- private void init(Context context) {
- ArrayList<String> months = new ArrayList<String>();
- mCalendar.set(Calendar.DAY_OF_MONTH, 1);
- for (int i = 0; i < NUM_MONTHS; i++) {
- mCalendar.set(Calendar.MONTH, i);
- months.add(mCalendar.getDisplayName(Calendar.MONTH, Calendar.SHORT,
- Locale.getDefault()).toUpperCase(Locale.getDefault()));
- }
- setAdapter(new ArrayAdapter<String>(context, R.layout.month_text_view, months));
- }
-
- public class MonthPickerAdapter extends SimpleAdapter {
-
- /**
- * @param context
- * @param data
- * @param resource
- * @param from
- * @param to
- */
- public MonthPickerAdapter(Context context,
- List<? extends Map<String, ?>> data,
- int resource, String[] from, int[] to) {
- super(context, data, resource, from, to);
- }
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- mController.onMonthPickerSelectionChanged(position);
- }
-}
diff --git a/src/com/android/datetimepicker/date/OnDateChangedListener.java b/src/com/android/datetimepicker/date/OnDateChangedListener.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/com/android/datetimepicker/date/OnDateChangedListener.java
diff --git a/src/com/android/datetimepicker/date/SimpleMonthAdapter.java b/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
index 533776e..6d3ef7a 100644
--- a/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
+++ b/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
@@ -207,7 +207,8 @@ public class SimpleMonthAdapter extends BaseAdapter implements OnTouchListener {
* @param day The day that was tapped
*/
protected void onDayTapped(CalendarDay day) {
- mController.onDayPickerSelectionChanged(day.year, day.month, day.day);
+ mController.tryVibrate();
+ mController.onDayOfMonthSelected(day.year, day.month, day.day);
setSelectedDay(day);
}
diff --git a/src/com/android/datetimepicker/date/SimpleMonthView.java b/src/com/android/datetimepicker/date/SimpleMonthView.java
index 666c43e..1beeef6 100644
--- a/src/com/android/datetimepicker/date/SimpleMonthView.java
+++ b/src/com/android/datetimepicker/date/SimpleMonthView.java
@@ -22,7 +22,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
-import android.graphics.Rect;
+import android.graphics.Typeface;
import android.text.format.Time;
import android.view.View;
@@ -110,9 +110,12 @@ public class SimpleMonthView extends View {
// affects the padding on the sides of this view
protected int mPadding = 0;
- protected Rect r = new Rect();
+ private String mDayOfWeekTypeface;
+ private String mMonthTitleTypeface;
+
protected Paint mMonthNumPaint;
protected Paint mMonthTitlePaint;
+ protected Paint mMonthTitleBGPaint;
protected Paint mSelectedCirclePaint;
protected Paint mMonthDayLabelPaint;
@@ -152,15 +155,10 @@ public class SimpleMonthView extends View {
private int mNumRows = DEFAULT_NUM_ROWS;
- protected int mBGColor;
- protected int mFocusMonthColor;
- protected int mOtherMonthColor;
- protected int mDaySeparatorColor;
- protected int mTodayOutlineColor;
- protected int mWeekNumColor;
-
protected int mDayTextColor;
- protected int mMonthTitleTextColor;
+ protected int mTodayNumberColor;
+ protected int mMonthTitleColor;
+ protected int mMonthTitleBGColor;
public SimpleMonthView(Context context) {
super(context);
@@ -169,14 +167,14 @@ public class SimpleMonthView extends View {
mDayLabelCalendar = Calendar.getInstance();
mCalendar = Calendar.getInstance();
- mBGColor = res.getColor(R.color.month_bgcolor);
- mFocusMonthColor = res.getColor(R.color.month_mini_day_number);
- mOtherMonthColor = res.getColor(R.color.month_other_month_day_number);
- mDaySeparatorColor = res.getColor(R.color.month_grid_lines);
- mTodayOutlineColor = res.getColor(R.color.mini_month_today_outline_color);
- mDayTextColor = res.getColor(R.color.calendar_day_number);
- mMonthTitleTextColor = res.getColor(R.color.selected_text);
- mWeekNumColor = res.getColor(R.color.month_week_num_color);
+
+ mDayOfWeekTypeface = res.getString(R.string.day_of_week_label_typeface);
+ mMonthTitleTypeface = res.getString(R.string.sans_serif);
+
+ mDayTextColor = res.getColor(R.color.date_picker_text_normal);
+ mTodayNumberColor = res.getColor(R.color.blue);
+ mMonthTitleColor = res.getColor(R.color.white);
+ mMonthTitleBGColor = res.getColor(R.color.circle_background);
MINI_DAY_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.day_number_size);
MONTH_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.month_label_size);
@@ -200,15 +198,22 @@ public class SimpleMonthView extends View {
mMonthTitlePaint.setFakeBoldText(true);
mMonthTitlePaint.setAntiAlias(true);
mMonthTitlePaint.setTextSize(MONTH_LABEL_TEXT_SIZE);
- mMonthTitlePaint.setColor(mMonthTitleTextColor);
+ mMonthTitlePaint.setTypeface(Typeface.create(mMonthTitleTypeface, Typeface.BOLD));
+ mMonthTitlePaint.setColor(mDayTextColor);
mMonthTitlePaint.setTextAlign(Align.CENTER);
mMonthTitlePaint.setStyle(Style.FILL);
- mMonthTitlePaint.setFakeBoldText(true);
+
+ mMonthTitleBGPaint = new Paint();
+ mMonthTitleBGPaint.setFakeBoldText(true);
+ mMonthTitleBGPaint.setAntiAlias(true);
+ mMonthTitleBGPaint.setColor(mMonthTitleBGColor);
+ mMonthTitleBGPaint.setTextAlign(Align.CENTER);
+ mMonthTitleBGPaint.setStyle(Style.FILL);
mSelectedCirclePaint = new Paint();
mSelectedCirclePaint.setFakeBoldText(true);
mSelectedCirclePaint.setAntiAlias(true);
- mSelectedCirclePaint.setColor(mMonthTitleTextColor);
+ mSelectedCirclePaint.setColor(mTodayNumberColor);
mSelectedCirclePaint.setTextAlign(Align.CENTER);
mSelectedCirclePaint.setStyle(Style.FILL);
mSelectedCirclePaint.setAlpha(SELECTED_CIRCLE_ALPHA);
@@ -217,6 +222,7 @@ public class SimpleMonthView extends View {
mMonthDayLabelPaint.setAntiAlias(true);
mMonthDayLabelPaint.setTextSize(MONTH_DAY_LABEL_TEXT_SIZE);
mMonthDayLabelPaint.setColor(mDayTextColor);
+ mMonthDayLabelPaint.setTypeface(Typeface.create(mDayOfWeekTypeface, Typeface.NORMAL));
mMonthDayLabelPaint.setStyle(Style.FILL);
mMonthDayLabelPaint.setTextAlign(Align.CENTER);
mMonthDayLabelPaint.setFakeBoldText(true);
@@ -370,7 +376,7 @@ public class SimpleMonthView extends View {
}
if (mHasToday && mToday == dayNumber) {
- mMonthNumPaint.setColor(mMonthTitleTextColor);
+ mMonthNumPaint.setColor(mTodayNumberColor);
} else {
mMonthNumPaint.setColor(mDayTextColor);
}
diff --git a/src/com/android/datetimepicker/date/SelectableTextView.java b/src/com/android/datetimepicker/date/TextViewWithCircularIndicator.java
index 0da34fd..66140f5 100644
--- a/src/com/android/datetimepicker/date/SelectableTextView.java
+++ b/src/com/android/datetimepicker/date/TextViewWithCircularIndicator.java
@@ -28,9 +28,9 @@ import android.widget.TextView;
import com.android.datetimepicker.R;
/**
- * A text view which, when pressed or selected, displays a blue circle around the text.
+ * A text view which, when pressed or activated, displays a blue circle around the text.
*/
-public class SelectableTextView extends TextView {
+public class TextViewWithCircularIndicator extends TextView {
private static final int SELECTED_CIRCLE_ALPHA = 60;
@@ -38,11 +38,12 @@ public class SelectableTextView extends TextView {
private final int mRadius;
private final int mCircleColor;
+ private boolean mDrawCircle;
- public SelectableTextView(Context context, AttributeSet attrs) {
+ public TextViewWithCircularIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
Resources res = context.getResources();
- mCircleColor = res.getColor(R.color.selected_text);
+ mCircleColor = res.getColor(R.color.blue);
mRadius = res.getDimensionPixelOffset(R.dimen.month_select_circle_radius);
init();
}
@@ -56,12 +57,18 @@ public class SelectableTextView extends TextView {
mCirclePaint.setAlpha(SELECTED_CIRCLE_ALPHA);
}
+ public void drawIndicator(boolean drawCircle) {
+ mDrawCircle = drawCircle;
+ }
+
@Override
public void onDraw(Canvas canvas) {
- if (isPressed() || isSelected()) {
- canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius,
- mCirclePaint);
- }
super.onDraw(canvas);
+ if (mDrawCircle) {
+ final int width = getWidth();
+ final int height = getHeight();
+ int radius = Math.min(width, height) / 2;
+ canvas.drawCircle(width / 2, height / 2, radius, mCirclePaint);
+ }
}
}
diff --git a/src/com/android/datetimepicker/date/YearPickerView.java b/src/com/android/datetimepicker/date/YearPickerView.java
index 5134879..10847f2 100644
--- a/src/com/android/datetimepicker/date/YearPickerView.java
+++ b/src/com/android/datetimepicker/date/YearPickerView.java
@@ -17,52 +17,129 @@
package com.android.datetimepicker.date;
import android.content.Context;
-import android.view.Gravity;
+import android.content.res.Resources;
+import android.graphics.drawable.StateListDrawable;
+import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.NumberPicker;
-import android.widget.NumberPicker.OnValueChangeListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.datetimepicker.R;
+import com.android.datetimepicker.date.DatePickerDialog.OnDateChangedListener;
+
+import java.util.ArrayList;
+import java.util.List;
/**
- * A number picker allowing a user to choose a specific year.
+ * Displays a selectable list of years.
*/
-public class YearPickerView extends FrameLayout implements OnValueChangeListener {
+public class YearPickerView extends ListView implements OnItemClickListener, OnDateChangedListener {
- private final NumberPicker mPicker;
private final DatePickerController mController;
+ private YearAdapter mAdapter;
+ private int mViewSize;
+ private int mChildSize;
+ private TextViewWithCircularIndicator mSelectedView;
+ /**
+ * @param context
+ */
public YearPickerView(Context context, DatePickerController controller) {
super(context);
mController = controller;
+ mController.registerOnDateChangedListener(this);
+ setVerticalFadingEdgeEnabled(true);
ViewGroup.LayoutParams frame = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- setLayoutParams(frame);
- mPicker = new NumberPicker(context);
- LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
- params.gravity = Gravity.CENTER;
- mPicker.setLayoutParams(params);
- mPicker.setOnLongPressUpdateInterval(100);
- mPicker.setMinValue(controller.getMinYear());
- mPicker.setMaxValue(controller.getMaxYear());
- mPicker.setWrapSelectorWheel(false);
- mPicker.setValue(controller.getSelectedDay().year);
- mPicker.setOnValueChangedListener(this);
- addView(mPicker);
+ setLayoutParams(frame);
+ Resources res = context.getResources();
+ mViewSize = res.getDimensionPixelOffset(R.dimen.pager_height);
+ mChildSize = res.getDimensionPixelOffset(R.dimen.year_label_height);
+ setFadingEdgeLength(mChildSize / 3);
+ init(context);
+ setOnItemClickListener(this);
+ setSelector(new StateListDrawable());
+ setDividerHeight(0);
+ onDateChanged();
+ }
+
+ private void init(Context context) {
+ ArrayList<String> years = new ArrayList<String>();
+ for (int year = mController.getMinYear(); year <= mController.getMaxYear(); year++) {
+ years.add(Integer.valueOf(year).toString());
+ }
+ mAdapter = new YearAdapter(context, R.layout.year_label_text_view, years);
+ setAdapter(mAdapter);
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ mController.tryVibrate();
+ TextViewWithCircularIndicator clickedView = (TextViewWithCircularIndicator) view;
+ if (mSelectedView != clickedView) {
+ mSelectedView.drawIndicator(false);
+ mSelectedView.requestLayout();
+ clickedView.drawIndicator(true);
+ clickedView.requestLayout();
+ mSelectedView = clickedView;
+ }
+ mController.onYearSelected(getYearFromTextView(clickedView));
+ mAdapter.notifyDataSetChanged();
}
- public void setValue(int value) {
- mPicker.setValue(value);
+ private int getYearFromTextView(TextView view) {
+ return Integer.valueOf(view.getText().toString());
}
- public void onChange() {
- mPicker.setMinValue(mController.getMinYear());
- mPicker.setMaxValue(mController.getMaxYear());
- requestLayout();
+ private class YearAdapter extends ArrayAdapter<String> {
+
+ public YearAdapter(Context context, int resource, List<String> objects) {
+ super(context, resource, objects);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextViewWithCircularIndicator v = (TextViewWithCircularIndicator)
+ super.getView(position, convertView, parent);
+ v.requestLayout();
+ int year = getYearFromTextView(v);
+ boolean selected = mController.getSelectedDay().year == year;
+ v.drawIndicator(selected);
+ if (selected) {
+ mSelectedView = v;
+ }
+ return v;
+ }
+ }
+
+ public void postSetSelection(final int position) {
+ post(new Runnable() {
+
+ @Override
+ public void run() {
+ setSelection(position);
+ requestLayout();
+ }
+ });
+ }
+
+ public void postSetSelectionFromTop(final int position) {
+ post(new Runnable() {
+
+ @Override
+ public void run() {
+ setSelectionFromTop(position, mViewSize / 2 - mChildSize / 2);
+ requestLayout();
+ }
+ });
}
@Override
- public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- mController.onYearPickerSelectionChanged(newVal);
+ public void onDateChanged() {
+ mAdapter.notifyDataSetChanged();
+ postSetSelectionFromTop(mController.getSelectedDay().year - mController.getMinYear());
}
}
diff --git a/src/com/android/datetimepicker/time/TimePickerDialog.java b/src/com/android/datetimepicker/time/TimePickerDialog.java
index a5ef395..27742a2 100644
--- a/src/com/android/datetimepicker/time/TimePickerDialog.java
+++ b/src/com/android/datetimepicker/time/TimePickerDialog.java
@@ -36,9 +36,8 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.datetimepicker.R;
-
-import com.android.datetimepicker.time.RadialPickerLayout.OnValueSelectedListener;
import com.android.datetimepicker.Utils;
+import com.android.datetimepicker.time.RadialPickerLayout.OnValueSelectedListener;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
@@ -404,7 +403,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
mHourView.setTextColor(hourColor);
mMinuteView.setTextColor(minuteColor);
- ObjectAnimator pulseAnimator = Utils.getPulseAnimator(labelToAnimate);
+ ObjectAnimator pulseAnimator = Utils.getPulseAnimator(labelToAnimate, 0.85f, 1.1f);
if (delayLabelAnimate) {
pulseAnimator.setStartDelay(PULSE_ANIMATOR_DELAY);
}