1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.launcher2; 18 19 import android.os.Handler; 20 import android.os.Message; 21 import android.os.SystemClock; 22 import android.util.Log; 23 24 /** 25 * Provides an animation between 0.0f and 1.0f over a given duration. 26 */ 27 class SymmetricalLinearTween { 28 29 private static final int FPS = 30; 30 private static final int FRAME_TIME = 1000 / FPS; 31 32 Handler mHandler; 33 int mDuration; 34 TweenCallback mCallback; 35 36 boolean mRunning; 37 long mBase; 38 boolean mDirection; 39 float mValue; 40 41 /** 42 * @param duration milliseconds duration 43 * @param callback callbacks 44 */ 45 public SymmetricalLinearTween(boolean initial, int duration, TweenCallback callback) { 46 mValue = initial ? 1.0f : 0.0f; 47 mDirection = initial; 48 mDuration = duration; 49 mCallback = callback; 50 mHandler = new Handler(); 51 } 52 53 /** 54 * Starts the tweening. 55 * 56 * @param direction If direction is true, the value goes towards 1.0f. If direction 57 * is false, the value goes towards 0.0f. 58 */ 59 public void start(boolean direction) { 60 start(direction, SystemClock.uptimeMillis()); 61 } 62 63 /** 64 * Starts the tweening. 65 * 66 * @param direction If direction is true, the value goes towards 1.0f. If direction 67 * is false, the value goes towards 0.0f. 68 * @param baseTime The time to use as zero for this animation, in the 69 * {@link SystemClock.uptimeMillis} time base. This allows you to 70 * synchronize multiple animations. 71 */ 72 public void start(boolean direction, long baseTime) { 73 if (direction != mDirection) { 74 if (!mRunning) { 75 mBase = baseTime; 76 mRunning = true; 77 mCallback.onTweenStarted(); 78 long next = SystemClock.uptimeMillis() + FRAME_TIME; 79 mHandler.postAtTime(mTick, next); 80 } else { 81 // reverse direction 82 long now = SystemClock.uptimeMillis(); 83 long diff = now - mBase; 84 mBase = now + diff - mDuration; 85 } 86 mDirection = direction; 87 } 88 } 89 90 Runnable mTick = new Runnable() { 91 public void run() { 92 long base = mBase; 93 long now = SystemClock.uptimeMillis(); 94 long diff = now-base; 95 int duration = mDuration; 96 float val = diff/(float)duration; 97 if (!mDirection) { 98 val = 1.0f - val; 99 } 100 if (val > 1.0f) { 101 val = 1.0f; 102 } else if (val < 0.0f) { 103 val = 0.0f; 104 } 105 float old = mValue; 106 mValue = val; 107 mCallback.onTweenValueChanged(val, old); 108 int frame = (int)(diff / FRAME_TIME); 109 long next = base + ((frame+1)*FRAME_TIME); 110 if (diff < duration) { 111 mHandler.postAtTime(this, next); 112 } 113 if (diff >= duration) { 114 mCallback.onTweenFinished(); 115 mRunning = false; 116 } 117 } 118 }; 119 } 120 121