diff options
author | Sam Blitzstein <sblitz@google.com> | 2013-04-09 20:34:59 -0700 |
---|---|---|
committer | Sam Blitzstein <sblitz@google.com> | 2013-04-10 15:05:47 -0700 |
commit | b612bb9493d006667f767c59278f8d0925dbd9f6 (patch) | |
tree | e2528c772a747abbecea637da79919f05158e781 | |
parent | 2352366238143a07597a95715bb1feee5449e2f2 (diff) | |
download | datetimepicker-b612bb9493d006667f767c59278f8d0925dbd9f6.tar.gz |
Add pulsating effect to header label when switching view.
Bug: 8570362
Change-Id: Ie8534f5be227605ee17d14e558f3398f9d7c6ed7
-rw-r--r-- | res/layout-land/time_picker_dialog.xml | 6 | ||||
-rw-r--r-- | res/layout/time_header_label.xml | 67 | ||||
-rw-r--r-- | res/layout/time_picker_dialog.xml | 4 | ||||
-rw-r--r-- | res/values-sw600dp/dimens.xml | 1 | ||||
-rw-r--r-- | res/values/dimens.xml | 1 | ||||
-rw-r--r-- | src/com/android/datetimepicker/Utils.java | 25 | ||||
-rw-r--r-- | src/com/android/datetimepicker/time/TimePickerDialog.java | 34 |
7 files changed, 112 insertions, 26 deletions
diff --git a/res/layout-land/time_picker_dialog.xml b/res/layout-land/time_picker_dialog.xml index 4501d19..0d21f20 100644 --- a/res/layout-land/time_picker_dialog.xml +++ b/res/layout-land/time_picker_dialog.xml @@ -25,18 +25,18 @@ android:layout_marginTop="@dimen/minimum_margin_top_bottom" android:layout_marginBottom="@dimen/minimum_margin_top_bottom" > <LinearLayout - android:layout_width="wrap_content" + android:layout_width="@dimen/left_side_width" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout - android:layout_width="@dimen/left_side_width" + android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:background="@color/white" > <include layout="@layout/time_header_label" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/header_height" android:layout_gravity="center" /> </FrameLayout> <View diff --git a/res/layout/time_header_label.xml b/res/layout/time_header_label.xml index 8f64583..62a2ac5 100644 --- a/res/layout/time_header_label.xml +++ b/res/layout/time_header_label.xml @@ -16,23 +16,43 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="center" > + android:layout_height="match_parent" + android:layout_gravity="center" + android:background="@color/white" > <View android:id="@+id/empty_view" android:layout_width="1dp" android:layout_height="1dp" android:background="#00000000" android:layout_centerInParent="true" /> - <com.android.datetimepicker.FakeButton - android:id="@+id/hours" + <TextView + android:id="@+id/hour_space" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/time_placeholder" - android:textColor="@color/blue" android:layout_toLeftOf="@+id/separator" android:layout_centerVertical="true" - style="@style/time_label" /> + android:visibility="invisible" + style="@style/time_label" + android:importantForAccessibility="no" /> + <FrameLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_alignRight="@+id/hour_space" + android:layout_alignLeft="@+id/hour_space" + android:layout_marginLeft="@dimen/extra_time_label_margin" + android:layout_marginRight="@dimen/extra_time_label_margin" + android:layout_centerVertical="true" > + <com.android.datetimepicker.FakeButton + android:id="@+id/hours" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/time_placeholder" + android:textColor="@color/blue" + android:gravity="center_horizontal" + android:layout_gravity="center" + style="@style/time_label" /> + </FrameLayout> <TextView android:id="@+id/separator" android:layout_width="wrap_content" @@ -44,20 +64,39 @@ android:layout_centerVertical="true" style="@style/time_label" android:importantForAccessibility="no" /> - <com.android.datetimepicker.FakeButton - android:id="@+id/minutes" + <TextView + android:id="@+id/minutes_space" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/time_placeholder" android:layout_toRightOf="@+id/separator" android:layout_centerVertical="true" - style="@style/time_label" /> + android:visibility="invisible" + style="@style/time_label" + android:importantForAccessibility="no" /> + <FrameLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_alignRight="@+id/minutes_space" + android:layout_alignLeft="@+id/minutes_space" + android:layout_marginLeft="@dimen/extra_time_label_margin" + android:layout_marginRight="@dimen/extra_time_label_margin" + android:layout_centerVertical="true" > + <com.android.datetimepicker.FakeButton + android:id="@+id/minutes" + style="@style/time_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:text="@string/time_placeholder" + android:layout_gravity="center" /> + </FrameLayout> <com.android.datetimepicker.FakeButton android:id="@+id/ampm_hitspace" android:layout_width="@dimen/ampm_label_size" android:layout_height="wrap_content" - android:layout_alignTop="@+id/minutes" - android:layout_alignBottom="@+id/minutes" + android:layout_alignParentTop="true" + android:layout_alignParentBottom="true" android:layout_alignLeft="@+id/ampm_label" android:layout_alignRight="@+id/ampm_label" /> <TextView @@ -67,8 +106,8 @@ android:text="@string/time_placeholder" android:paddingLeft="@dimen/ampm_left_padding" android:paddingRight="@dimen/ampm_left_padding" - android:layout_toRightOf="@+id/minutes" - android:layout_alignBaseline="@+id/minutes" + android:layout_toRightOf="@+id/minutes_space" + android:layout_alignBaseline="@+id/separator" style="@style/ampm_label" android:importantForAccessibility="no" /> - </RelativeLayout>
\ No newline at end of file + </RelativeLayout> diff --git a/res/layout/time_picker_dialog.xml b/res/layout/time_picker_dialog.xml index 67f5977..07867d1 100644 --- a/res/layout/time_picker_dialog.xml +++ b/res/layout/time_picker_dialog.xml @@ -23,12 +23,12 @@ android:focusable="true" > <FrameLayout android:layout_width="match_parent" - android:layout_height="@dimen/header_height" + android:layout_height="wrap_content" android:background="@color/white" > <include layout="@layout/time_header_label" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/header_height" android:layout_gravity="center" /> </FrameLayout> <com.android.datetimepicker.time.RadialPickerLayout diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml index 03ddbca..68dbc70 100644 --- a/res/values-sw600dp/dimens.xml +++ b/res/values-sw600dp/dimens.xml @@ -40,6 +40,7 @@ <dimen name="month_day_label_text_size">15sp</dimen> <dimen name="time_label_size">75sp</dimen> + <dimen name="extra_time_label_margin">-50dp</dimen> <dimen name="ampm_label_size">20sp</dimen> <dimen name="ampm_left_padding">8dip</dimen> <dimen name="separator_padding">5dip</dimen> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 621cbf7..691ab0f 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -30,6 +30,7 @@ <dimen name="time_label_size">60sp</dimen> + <dimen name="extra_time_label_margin">-30dp</dimen> <dimen name="ampm_label_size">16sp</dimen> <dimen name="done_label_size">16sp</dimen> <dimen name="ampm_left_padding">6dip</dimen> diff --git a/src/com/android/datetimepicker/Utils.java b/src/com/android/datetimepicker/Utils.java index 9bc5952..ae3087b 100644 --- a/src/com/android/datetimepicker/Utils.java +++ b/src/com/android/datetimepicker/Utils.java @@ -16,8 +16,12 @@ package com.android.datetimepicker; +import android.animation.Keyframe; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; import android.os.Build; import android.text.format.Time; +import android.view.View; import java.util.Calendar; @@ -27,6 +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; static final String SHARED_PREFS_NAME = "com.android.calendar_preferences"; @@ -92,4 +97,24 @@ public class Utils { int refDay = Time.EPOCH_JULIAN_DAY - diff; return (julianDay - refDay) / 7; } + + /** + * Render an animator to pulsate a view in place. + * @param labelToAnimate the view to pulsate. + * @return The animator object. Use .start() to begin. + */ + public static ObjectAnimator getPulseAnimator(View labelToAnimate) { + Keyframe k0 = Keyframe.ofFloat(0f, 1f); + Keyframe k1 = Keyframe.ofFloat(0.25f, 0.85f); + Keyframe k2 = Keyframe.ofFloat(0.625f, 1.1f); + Keyframe k3 = Keyframe.ofFloat(1f, 1f); + + PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", k0, k1, k2, k3); + ObjectAnimator pulseAnimator = + ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY); + pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION); + + return pulseAnimator; + } } diff --git a/src/com/android/datetimepicker/time/TimePickerDialog.java b/src/com/android/datetimepicker/time/TimePickerDialog.java index 57ce93a..a5ef395 100644 --- a/src/com/android/datetimepicker/time/TimePickerDialog.java +++ b/src/com/android/datetimepicker/time/TimePickerDialog.java @@ -16,6 +16,7 @@ package com.android.datetimepicker.time; +import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.ActionBar.LayoutParams; import android.app.DialogFragment; @@ -65,11 +66,16 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL public static final int AM = 0; public static final int PM = 1; + // Delay before starting the pulse animation, in ms. + private static final int PULSE_ANIMATOR_DELAY = 300; + private OnTimeSetListener mCallback; private TextView mDoneButton; private TextView mHourView; + private TextView mHourSpaceView; private TextView mMinuteView; + private TextView mMinuteSpaceView; private TextView mAmPmTextView; private View mAmPmHitspace; private RadialPickerLayout mTimePicker; @@ -181,6 +187,8 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL mHourView = (TextView) view.findViewById(R.id.hours); mHourView.setOnKeyListener(keyboardListener); + mHourSpaceView = (TextView) view.findViewById(R.id.hour_space); + mMinuteSpaceView = (TextView) view.findViewById(R.id.minutes_space); mMinuteView = (TextView) view.findViewById(R.id.minutes); mMinuteView.setOnKeyListener(keyboardListener); mAmPmTextView = (TextView) view.findViewById(R.id.ampm_label); @@ -198,20 +206,20 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL savedInstanceState.containsKey(KEY_CURRENT_ITEM_SHOWING)) { currentItemShowing = savedInstanceState.getInt(KEY_CURRENT_ITEM_SHOWING); } - setCurrentItemShowing(currentItemShowing, false, true); + setCurrentItemShowing(currentItemShowing, false, true, true); mTimePicker.invalidate(); mHourView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - setCurrentItemShowing(HOUR_INDEX, true, true); + setCurrentItemShowing(HOUR_INDEX, true, false, true); mTimePicker.tryVibrate(); } }); mMinuteView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - setCurrentItemShowing(MINUTE_INDEX, true, true); + setCurrentItemShowing(MINUTE_INDEX, true, false, true); mTimePicker.tryVibrate(); } }); @@ -320,7 +328,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL setHour(newValue, false); String announcement = String.format("%d", newValue); if (mAllowAutoAdvance && autoAdvance) { - setCurrentItemShowing(MINUTE_INDEX, true, false); + setCurrentItemShowing(MINUTE_INDEX, true, true, false); announcement += ". " + mSelectMinutes; } tryAccessibilityAnnounce(announcement); @@ -350,6 +358,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL CharSequence text = String.format(format, value); mHourView.setText(text); + mHourSpaceView.setText(text); if (announce) { tryAccessibilityAnnounce(text); } @@ -362,12 +371,15 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL CharSequence text = String.format(Locale.getDefault(), "%02d", value); tryAccessibilityAnnounce(text); mMinuteView.setText(text); + mMinuteSpaceView.setText(text); } // Show either Hours or Minutes. - private void setCurrentItemShowing(int index, boolean animate, boolean announce) { - mTimePicker.setCurrentItemShowing(index, animate); + private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate, + boolean announce) { + mTimePicker.setCurrentItemShowing(index, animateCircle); + TextView labelToAnimate; if (index == HOUR_INDEX) { int hours = mTimePicker.getHours(); if (!mIs24HourMode) { @@ -377,18 +389,26 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL if (announce) { tryAccessibilityAnnounce(mSelectHours); } + labelToAnimate = mHourView; } else { int minutes = mTimePicker.getMinutes(); mTimePicker.setContentDescription(mMinutePickerDescription+": "+minutes); if (announce) { tryAccessibilityAnnounce(mSelectMinutes); } + labelToAnimate = mMinuteView; } int hourColor = (index == HOUR_INDEX)? mBlue : mBlack; int minuteColor = (index == MINUTE_INDEX)? mBlue : mBlack; mHourView.setTextColor(hourColor); mMinuteView.setTextColor(minuteColor); + + ObjectAnimator pulseAnimator = Utils.getPulseAnimator(labelToAnimate); + if (delayLabelAnimate) { + pulseAnimator.setStartDelay(PULSE_ANIMATOR_DELAY); + } + pulseAnimator.start(); } /** @@ -581,7 +601,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL if (!mIs24HourMode) { updateAmPmDisplay(hour < 12? AM : PM); } - setCurrentItemShowing(mTimePicker.getCurrentItemShowing(), true, true); + setCurrentItemShowing(mTimePicker.getCurrentItemShowing(), true, true, true); mDoneButton.setEnabled(true); } else { Boolean[] enteredZeros = {false, false}; |