diff options
author | Jim Miller <jaggies@google.com> | 2009-11-16 23:08:35 -0800 |
---|---|---|
committer | Jim Miller <jaggies@google.com> | 2009-11-16 23:08:35 -0800 |
commit | 4f01d4a4da7754dbe6a49cca8f94e81104acb87f (patch) | |
tree | fee02956c0fccf06ad30bbd02cbc21e83310c924 /core/java | |
parent | f36b8f439babc141970b1207d1d9c12b7a14c468 (diff) | |
download | frameworks_base-4f01d4a4da7754dbe6a49cca8f94e81104acb87f.zip frameworks_base-4f01d4a4da7754dbe6a49cca8f94e81104acb87f.tar.gz frameworks_base-4f01d4a4da7754dbe6a49cca8f94e81104acb87f.tar.bz2 |
Fix 2209086: Clean up visual glitches in SlidingTab for lock and incall screen.
This fixes the following glitches:
- flash at the end of animation as the widget resets. Fix: new "hold" animation holds the view for 1 second, allowing it to transition before we reset the view.
- target flashing. Fix: remove AlphaAnimation when we want to hide the target.
- bar appears to get stuck at edge. Fix: sliding bar now slides fully offscreen when hold == true. Added setHoldAfterTrigger() method to allow InCallScreen and LockScreen to have different behaviors.
- view continues to animate when shown again. Fix: reset the animations and sliders when the view is hidden.
Tested:
Answer/Decline call on CDMA and GSM device.
Unlock phone and toggle sound on/off in LockScreen on both devices.
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/com/android/internal/widget/SlidingTab.java | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java index b5a0a55..b7dd27d 100644 --- a/core/java/com/android/internal/widget/SlidingTab.java +++ b/core/java/com/android/internal/widget/SlidingTab.java @@ -64,6 +64,8 @@ public class SlidingTab extends ViewGroup { private static final int TRACKING_MARGIN = 50; private static final int ANIM_DURATION = 250; // Time for most animations (in ms) private static final int ANIM_TARGET_TIME = 500; // Time to show targets (in ms) + private boolean mHoldLeftOnTransition = true; + private boolean mHoldRightOnTransition = true; private OnTriggerListener mOnTriggerListener; private int mGrabbedState = OnTriggerListener.NO_HANDLE; @@ -86,6 +88,23 @@ public class SlidingTab extends ViewGroup { private Rect mTmpRect; /** + * Listener used to reset the view when the current animation completes. + */ + private final AnimationListener mAnimationDoneListener = new AnimationListener() { + public void onAnimationStart(Animation animation) { + + } + + public void onAnimationRepeat(Animation animation) { + + } + + public void onAnimationEnd(Animation animation) { + onAnimationDone(); + } + }; + + /** * Interface definition for a callback to be invoked when a tab is triggered * by moving it beyond a threshold. */ @@ -274,7 +293,6 @@ public class SlidingTab extends ViewGroup { alphaAnim.setDuration(ANIM_TARGET_TIME); target.startAnimation(alphaAnim); target.setVisibility(View.VISIBLE); - target.startAnimation(alphaAnim); } void reset(boolean animate) { @@ -302,6 +320,9 @@ public class SlidingTab extends ViewGroup { text.offsetTopAndBottom(dy); tab.offsetTopAndBottom(dy); } + text.clearAnimation(); + tab.clearAnimation(); + target.clearAnimation(); } } @@ -406,7 +427,11 @@ public class SlidingTab extends ViewGroup { public void startAnimation(Animation animation) { tab.startAnimation(animation); text.startAnimation(animation); - target.setVisibility(View.GONE); + } + + public void hideTarget() { + target.clearAnimation(); + target.setVisibility(View.INVISIBLE); } } @@ -522,6 +547,16 @@ public class SlidingTab extends ViewGroup { } @Override + public void setVisibility(int visibility) { + // Clear animations so sliders don't continue to animate when we show the widget again. + if (visibility != getVisibility() && visibility == View.INVISIBLE) { + mLeftSlider.reset(false); + mRightSlider.reset(false); + } + super.setVisibility(visibility); + } + + @Override public boolean onTouchEvent(MotionEvent event) { if (mTracking) { final int action = event.getAction(); @@ -546,10 +581,11 @@ public class SlidingTab extends ViewGroup { mTriggered = true; mTracking = false; mCurrentSlider.setState(Slider.STATE_ACTIVE); - dispatchTriggerEvent(mCurrentSlider == mLeftSlider ? + boolean isLeft = mCurrentSlider == mLeftSlider; + dispatchTriggerEvent(isLeft ? OnTriggerListener.LEFT_HANDLE : OnTriggerListener.RIGHT_HANDLE); - startAnimating(); + startAnimating(isLeft ? mHoldLeftOnTransition : mHoldRightOnTransition); setGrabbedState(OnTriggerListener.NO_HANDLE); } break; @@ -562,6 +598,7 @@ public class SlidingTab extends ViewGroup { mTriggered = false; mOtherSlider.show(true); mCurrentSlider.reset(false); + mCurrentSlider.hideTarget(); mCurrentSlider = null; mOtherSlider = null; setGrabbedState(OnTriggerListener.NO_HANDLE); @@ -572,40 +609,52 @@ public class SlidingTab extends ViewGroup { return mTracking || super.onTouchEvent(event); } - void startAnimating() { + void startAnimating(final boolean holdAfter) { mAnimating = true; - final Animation appear = new AlphaAnimation(0.5f, 1.0f); appear.setDuration(ANIM_DURATION); final Animation trans; - Slider slider = mCurrentSlider; - int dx; - int dy; + final Slider slider = mCurrentSlider; + final Slider other = mOtherSlider; + final int dx; + final int dy; if (isHorizontal()) { int right = slider.tab.getRight(); int width = slider.tab.getWidth(); int left = slider.tab.getLeft(); int viewWidth = getWidth(); - dx = slider == mRightSlider ? - (right + viewWidth - width) - : (viewWidth - left) + viewWidth - width; + int holdOffset = holdAfter ? 0 : width; // how much of tab to show at the end of anim + dx = slider == mRightSlider ? - (right + viewWidth - holdOffset) + : (viewWidth - left) + viewWidth - holdOffset; dy = 0; } else { int top = slider.tab.getTop(); int bottom = slider.tab.getBottom(); int height = slider.tab.getHeight(); int viewHeight = getHeight(); + int holdOffset = holdAfter ? 0 : height; // how much of tab to show at end of anim dx = 0; - dy = slider == mRightSlider ? (top + viewHeight - height) - : - ((viewHeight - bottom) + viewHeight - height); + dy = slider == mRightSlider ? (top + viewHeight - holdOffset) + : - ((viewHeight - bottom) + viewHeight - holdOffset); } trans = new TranslateAnimation(0, dx, 0, dy); trans.setDuration(ANIM_DURATION); trans.setInterpolator(new LinearInterpolator()); + trans.setFillAfter(true); trans.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { - resetView(); - mLeftSlider.startAnimation(appear); - mRightSlider.startAnimation(appear); - mAnimating = false; + Animation anim; + if (holdAfter) { + anim = new TranslateAnimation(dx, dx, dy, dy); + anim.setDuration(1000); // plenty of time for transitions + mAnimating = false; + } else { + anim = new AlphaAnimation(0.5f, 1.0f); + anim.setDuration(ANIM_DURATION); + resetView(); + } + anim.setAnimationListener(mAnimationDoneListener); + mLeftSlider.startAnimation(anim); + mRightSlider.startAnimation(anim); } public void onAnimationRepeat(Animation animation) { @@ -618,9 +667,15 @@ public class SlidingTab extends ViewGroup { }); + slider.hideTarget(); slider.startAnimation(trans); } + private void onAnimationDone() { + resetView(); + mAnimating = false; + } + private boolean withinView(final float x, final float y, final View view) { return isHorizontal() && y > - TRACKING_MARGIN && y < TRACKING_MARGIN + view.getHeight() || !isHorizontal() && x > -TRACKING_MARGIN && x < TRACKING_MARGIN + view.getWidth(); @@ -643,8 +698,6 @@ public class SlidingTab extends ViewGroup { // Center the widgets in the view mLeftSlider.layout(l, t, r, b, isHorizontal() ? Slider.ALIGN_LEFT : Slider.ALIGN_BOTTOM); mRightSlider.layout(l, t, r, b, isHorizontal() ? Slider.ALIGN_RIGHT : Slider.ALIGN_TOP); - - invalidate(); // TODO: be more conservative about what we're invalidating } private void moveHandle(float x, float y) { @@ -722,6 +775,11 @@ public class SlidingTab extends ViewGroup { } } + public void setHoldAfterTrigger(boolean holdLeft, boolean holdRight) { + mHoldLeftOnTransition = holdLeft; + mHoldRightOnTransition = holdRight; + } + /** * Triggers haptic feedback. */ |