M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import android.content.Context;
import android.util.AttributeSet;
/**
* An interpolator where the rate of change starts and ends slowly but
* accelerates through the middle.
*
*/
public class AccelerateDecelerateInterpolator implements Interpolator {
public AccelerateDecelerateInterpolator() {
}
@SuppressWarnings({"UnusedDeclaration"})
public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
}
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An interpolator where the rate of change starts out slowly and
* and then accelerates.
*
*/
public class AccelerateInterpolator implements Interpolator {
private final float mFactor;
private final double mDoubleFactor;
public AccelerateInterpolator() {
mFactor = 1.0f;
mDoubleFactor = 2.0;
}
/**
* Constructor
*
* @param factor Degree to which the animation should be eased. Seting
* factor to 1.0f produces a y=x^2 parabola. Increasing factor above
* 1.0f exaggerates the ease-in effect (i.e., it starts even
* slower and ends evens faster)
*/
public AccelerateInterpolator(float factor) {
mFactor = factor;
mDoubleFactor = 2 * mFactor;
}
public AccelerateInterpolator(Context context, AttributeSet attrs) {
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);
mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);
mDoubleFactor = 2 * mFactor;
a.recycle();
}
public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return input * input;
} else {
return (float)Math.pow(input, mDoubleFactor);
}
}
}
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An animation that controls the alpha level of an object.
* Useful for fading things in and out. This animation ends up
* changing the alpha property of a {@link Transformation}
*
*/
public class AlphaAnimation extends Animation {
private float mFromAlpha;
private float mToAlpha;
/**
* Constructor used when an AlphaAnimation is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public AlphaAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AlphaAnimation);
mFromAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_fromAlpha, 1.0f);
mToAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_toAlpha, 1.0f);
a.recycle();
}
/**
* Constructor to use when building an AlphaAnimation from code
*
* @param fromAlpha Starting alpha value for the animation, where 1.0 means
* fully opaque and 0.0 means fully transparent.
* @param toAlpha Ending alpha value for the animation.
*/
public AlphaAnimation(float fromAlpha, float toAlpha) {
mFromAlpha = fromAlpha;
mToAlpha = toAlpha;
}
/**
* Changes the alpha property of the supplied {@link Transformation}
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
@Override
public boolean willChangeTransformationMatrix() {
return false;
}
@Override
public boolean willChangeBounds() {
return false;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,455 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.graphics.RectF;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a group of Animations that should be played together.
* The transformation of each individual animation are composed
* together into a single transform.
* If AnimationSet sets any properties that its children also set
* (for example, duration or fillBefore), the values of AnimationSet
* override the child values.
*/
public class AnimationSet extends Animation {
private static final int PROPERTY_FILL_AFTER_MASK = 0x1;
private static final int PROPERTY_FILL_BEFORE_MASK = 0x2;
private static final int PROPERTY_REPEAT_MODE_MASK = 0x4;
private static final int PROPERTY_START_OFFSET_MASK = 0x8;
private static final int PROPERTY_SHARE_INTERPOLATOR_MASK = 0x10;
private static final int PROPERTY_DURATION_MASK = 0x20;
private static final int PROPERTY_MORPH_MATRIX_MASK = 0x40;
private static final int PROPERTY_CHANGE_BOUNDS_MASK = 0x80;
private int mFlags = 0;
private ArrayList<Animation> mAnimations = new ArrayList<Animation>();
private Transformation mTempTransformation = new Transformation();
private long mLastEnd;
private long[] mStoredOffsets;
/**
* Constructor used when an AnimationSet is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public AnimationSet(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AnimationSet);
setFlag(PROPERTY_SHARE_INTERPOLATOR_MASK,
a.getBoolean(com.android.internal.R.styleable.AnimationSet_shareInterpolator, true));
init();
a.recycle();
}
/**
* Constructor to use when building an AnimationSet from code
*
* @param shareInterpolator Pass true if all of the animations in this set
* should use the interpolator assocciated with this AnimationSet.
* Pass false if each animation should use its own interpolator.
*/
public AnimationSet(boolean shareInterpolator) {
setFlag(PROPERTY_SHARE_INTERPOLATOR_MASK, shareInterpolator);
init();
}
@Override
protected AnimationSet clone() throws CloneNotSupportedException {
final AnimationSet animation = (AnimationSet) super.clone();
animation.mTempTransformation = new Transformation();
animation.mAnimations = new ArrayList<Animation>();
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
for (int i = 0; i < count; i++) {
animation.mAnimations.add(animations.get(i).clone());
}
return animation;
}
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
} else {
mFlags &= ~mask;
}
}
private void init() {
mStartTime = 0;
mDuration = 0;
}
@Override
public void setFillAfter(boolean fillAfter) {
mFlags |= PROPERTY_FILL_AFTER_MASK;
super.setFillAfter(fillAfter);
}
@Override
public void setFillBefore(boolean fillBefore) {
mFlags |= PROPERTY_FILL_BEFORE_MASK;
super.setFillBefore(fillBefore);
}
@Override
public void setRepeatMode(int repeatMode) {
mFlags |= PROPERTY_REPEAT_MODE_MASK;
super.setRepeatMode(repeatMode);
}
@Override
public void setStartOffset(long startOffset) {
mFlags |= PROPERTY_START_OFFSET_MASK;
super.setStartOffset(startOffset);
}
/**
* <p>Sets the duration of every child animation.</p>
*
* @param durationMillis the duration of the animation, in milliseconds, for
* every child in this set
*/
@Override
public void setDuration(long durationMillis) {
mFlags |= PROPERTY_DURATION_MASK;
super.setDuration(durationMillis);
}
/**
* Add a child animation to this animation set.
* The transforms of the child animations are applied in the order
* that they were added
* @param a Animation to add.
*/
public void addAnimation(Animation a) {
mAnimations.add(a);
boolean noMatrix = (mFlags & PROPERTY_MORPH_MATRIX_MASK) == 0;
if (noMatrix && a.willChangeTransformationMatrix()) {
mFlags |= PROPERTY_MORPH_MATRIX_MASK;
}
boolean changeBounds = (mFlags & PROPERTY_CHANGE_BOUNDS_MASK) == 0;
if (changeBounds && a.willChangeTransformationMatrix()) {
mFlags |= PROPERTY_CHANGE_BOUNDS_MASK;
}
if (mAnimations.size() == 1) {
mDuration = a.getStartOffset() + a.getDuration();
mLastEnd = mStartOffset + mDuration;
} else {
mLastEnd = Math.max(mLastEnd, a.getStartOffset() + a.getDuration());
mDuration = mLastEnd - mStartOffset;
}
}
/**
* Sets the start time of this animation and all child animations
*
* @see android.view.animation.Animation#setStartTime(long)
*/
@Override
public void setStartTime(long startTimeMillis) {
super.setStartTime(startTimeMillis);
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
for (int i = 0; i < count; i++) {
Animation a = animations.get(i);
a.setStartTime(startTimeMillis);
}
}
@Override
public long getStartTime() {
long startTime = Long.MAX_VALUE;
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
for (int i = 0; i < count; i++) {
Animation a = animations.get(i);
startTime = Math.min(startTime, a.getStartTime());
}
return startTime;
}
@Override
public void restrictDuration(long durationMillis) {
super.restrictDuration(durationMillis);
final ArrayList<Animation> animations = mAnimations;
int count = animations.size();
for (int i = 0; i < count; i++) {
animations.get(i).restrictDuration(durationMillis);
}
}
/**
* The duration of an AnimationSet is defined to be the
* duration of the longest child animation.
*
* @see android.view.animation.Animation#getDuration()
*/
@Override
public long getDuration() {
final ArrayList<Animation> animations = mAnimations;
final int count = animations.size();
long duration = 0;
boolean durationSet = (mFlags & PROPERTY_DURATION_MASK) == PROPERTY_DURATION_MASK;
if (durationSet) {
duration = mDuration;
} else {
for (int i = 0; i < count; i++) {
duration = Math.max(duration, animations.get(i).getDuration());
}
}
return duration;
}
/**
* The duration hint of an animation set is the maximum of the duration
* hints of all of its component animations.
*
* @see android.view.animation.Animation#computeDurationHint
*/
public long computeDurationHint() {
long duration = 0;
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
for (int i = count - 1; i >= 0; --i) {
final long d = animations.get(i).computeDurationHint();
if (d > duration) duration = d;
}
return duration;
}
/**
* @hide
*/
public void initializeInvalidateRegion(int left, int top, int right, int bottom) {
final RectF region = mPreviousRegion;
region.set(left, top, right, bottom);
region.inset(-1.0f, -1.0f);
if (mFillBefore) {
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
final Transformation temp = mTempTransformation;
final Transformation previousTransformation = mPreviousTransformation;
for (int i = count - 1; i >= 0; --i) {
final Animation a = animations.get(i);
temp.clear();
final Interpolator interpolator = a.mInterpolator;
a.applyTransformation(interpolator != null ? interpolator.getInterpolation(0.0f)
: 0.0f, temp);
previousTransformation.compose(temp);
}
}
}
/**
* The transformation of an animation set is the concatenation of all of its
* component animations.
*
* @see android.view.animation.Animation#getTransformation
*/
@Override
public boolean getTransformation(long currentTime, Transformation t) {
final int count = mAnimations.size();
final ArrayList<Animation> animations = mAnimations;
final Transformation temp = mTempTransformation;
boolean more = false;
boolean started = false;
boolean ended = true;
t.clear();
for (int i = count - 1; i >= 0; --i) {
final Animation a = animations.get(i);
temp.clear();
more = a.getTransformation(currentTime, temp) || more;
t.compose(temp);
started = started || a.hasStarted();
ended = a.hasEnded() && ended;
}
if (started && !mStarted) {
if (mListener != null) {
mListener.onAnimationStart(this);
}
mStarted = true;
}
if (ended != mEnded) {
if (mListener != null) {
mListener.onAnimationEnd(this);
}
mEnded = ended;
}
return more;
}
/**
* @see android.view.animation.Animation#scaleCurrentDuration(float)
*/
@Override
public void scaleCurrentDuration(float scale) {
final ArrayList<Animation> animations = mAnimations;
int count = animations.size();
for (int i = 0; i < count; i++) {
animations.get(i).scaleCurrentDuration(scale);
}
}
/**
* @see android.view.animation.Animation#initialize(int, int, int, int)
*/
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
boolean durationSet = (mFlags & PROPERTY_DURATION_MASK) == PROPERTY_DURATION_MASK;
boolean fillAfterSet = (mFlags & PROPERTY_FILL_AFTER_MASK) == PROPERTY_FILL_AFTER_MASK;
boolean fillBeforeSet = (mFlags & PROPERTY_FILL_BEFORE_MASK) == PROPERTY_FILL_BEFORE_MASK;
boolean repeatModeSet = (mFlags & PROPERTY_REPEAT_MODE_MASK) == PROPERTY_REPEAT_MODE_MASK;
boolean shareInterpolator = (mFlags & PROPERTY_SHARE_INTERPOLATOR_MASK)
== PROPERTY_SHARE_INTERPOLATOR_MASK;
boolean startOffsetSet = (mFlags & PROPERTY_START_OFFSET_MASK)
== PROPERTY_START_OFFSET_MASK;
if (shareInterpolator) {
ensureInterpolator();
}
final ArrayList<Animation> children = mAnimations;
final int count = children.size();
final long duration = mDuration;
final boolean fillAfter = mFillAfter;
final boolean fillBefore = mFillBefore;
final int repeatMode = mRepeatMode;
final Interpolator interpolator = mInterpolator;
final long startOffset = mStartOffset;
long[] storedOffsets = mStoredOffsets;
if (startOffsetSet) {
if (storedOffsets == null || storedOffsets.length != count) {
storedOffsets = mStoredOffsets = new long[count];
}
} else if (storedOffsets != null) {
storedOffsets = mStoredOffsets = null;
}
for (int i = 0; i < count; i++) {
Animation a = children.get(i);
if (durationSet) {
a.setDuration(duration);
}
if (fillAfterSet) {
a.setFillAfter(fillAfter);
}
if (fillBeforeSet) {
a.setFillBefore(fillBefore);
}
if (repeatModeSet) {
a.setRepeatMode(repeatMode);
}
if (shareInterpolator) {
a.setInterpolator(interpolator);
}
if (startOffsetSet) {
long offset = a.getStartOffset();
a.setStartOffset(offset + startOffset);
storedOffsets[i] = offset;
}
a.initialize(width, height, parentWidth, parentHeight);
}
}
@Override
public void reset() {
super.reset();
restoreChildrenStartOffset();
}
/**
* @hide
*/
void restoreChildrenStartOffset() {
final long[] offsets = mStoredOffsets;
if (offsets == null) return;
final ArrayList<Animation> children = mAnimations;
final int count = children.size();
for (int i = 0; i < count; i++) {
children.get(i).setStartOffset(offsets[i]);
}
}
/**
* @return All the child animations in this AnimationSet. Note that
* this may include other AnimationSets, which are not expanded.
*/
public List<Animation> getAnimations() {
return mAnimations;
}
@Override
public boolean willChangeTransformationMatrix() {
return (mFlags & PROPERTY_MORPH_MATRIX_MASK) == PROPERTY_MORPH_MATRIX_MASK;
}
@Override
public boolean willChangeBounds() {
return (mFlags & PROPERTY_CHANGE_BOUNDS_MASK) == PROPERTY_CHANGE_BOUNDS_MASK;
}
}
@@ -0,0 +1,320 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.content.res.Resources.NotFoundException;
import android.util.AttributeSet;
import android.util.Xml;
import android.os.SystemClock;
import java.io.IOException;
/**
* Defines common utilities for working with animations.
*
*/
public class AnimationUtils {
/**
* Returns the current animation time in milliseconds. This time should be used when invoking
* {@link Animation#setStartTime(long)}. Refer to {@link android.os.SystemClock} for more
* information about the different available clocks. The clock used by this method is
* <em>not</em> the "wall" clock (it is not {@link System#currentTimeMillis}).
*
* @return the current animation time in milliseconds
*
* @see android.os.SystemClock
*/
public static long currentAnimationTimeMillis() {
return SystemClock.uptimeMillis();
}
/**
* Loads an {@link Animation} object from a resource
*
* @param context Application context used to access resources
* @param id The resource id of the animation to load
* @return The animation object reference by the specified id
* @throws NotFoundException when the animation cannot be loaded
*/
public static Animation loadAnimation(Context context, int id)
throws NotFoundException {
XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
return createAnimationFromXml(context, parser);
} catch (XmlPullParserException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
if (parser != null) parser.close();
}
}
private static Animation createAnimationFromXml(Context c, XmlPullParser parser)
throws XmlPullParserException, IOException {
return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
}
private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
Animation anim = null;
// Make sure we are on a start tag.
int type;
int depth = parser.getDepth();
while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
&& type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("set")) {
anim = new AnimationSet(c, attrs);
createAnimationFromXml(c, parser, (AnimationSet)anim, attrs);
} else if (name.equals("alpha")) {
anim = new AlphaAnimation(c, attrs);
} else if (name.equals("scale")) {
anim = new ScaleAnimation(c, attrs);
} else if (name.equals("rotate")) {
anim = new RotateAnimation(c, attrs);
} else if (name.equals("translate")) {
anim = new TranslateAnimation(c, attrs);
} else {
throw new RuntimeException("Unknown animation name: " + parser.getName());
}
if (parent != null) {
parent.addAnimation(anim);
}
}
return anim;
}
public static LayoutAnimationController loadLayoutAnimation(Context context, int id)
throws NotFoundException {
XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
return createLayoutAnimationFromXml(context, parser);
} catch (XmlPullParserException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
if (parser != null) parser.close();
}
}
private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
XmlPullParser parser) throws XmlPullParserException, IOException {
return createLayoutAnimationFromXml(c, parser, Xml.asAttributeSet(parser));
}
private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException {
LayoutAnimationController controller = null;
int type;
int depth = parser.getDepth();
while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
&& type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if ("layoutAnimation".equals(name)) {
controller = new LayoutAnimationController(c, attrs);
} else if ("gridLayoutAnimation".equals(name)) {
controller = new GridLayoutAnimationController(c, attrs);
} else {
throw new RuntimeException("Unknown layout animation name: " + name);
}
}
return controller;
}
/**
* Make an animation for objects becoming visible. Uses a slide and fade
* effect.
*
* @param c Context for loading resources
* @param fromLeft is the object to be animated coming from the left
* @return The new animation
*/
public static Animation makeInAnimation(Context c, boolean fromLeft) {
Animation a;
if (fromLeft) {
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_left);
} else {
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_right);
}
a.setInterpolator(new DecelerateInterpolator());
a.setStartTime(currentAnimationTimeMillis());
return a;
}
/**
* Make an animation for objects becoming invisible. Uses a slide and fade
* effect.
*
* @param c Context for loading resources
* @param toRight is the object to be animated exiting to the right
* @return The new animation
*/
public static Animation makeOutAnimation(Context c, boolean toRight) {
Animation a;
if (toRight) {
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_right);
} else {
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_left);
}
a.setInterpolator(new AccelerateInterpolator());
a.setStartTime(currentAnimationTimeMillis());
return a;
}
/**
* Make an animation for objects becoming visible. Uses a slide up and fade
* effect.
*
* @param c Context for loading resources
* @return The new animation
*/
public static Animation makeInChildBottomAnimation(Context c) {
Animation a;
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_child_bottom);
a.setInterpolator(new AccelerateInterpolator());
a.setStartTime(currentAnimationTimeMillis());
return a;
}
/**
* Loads an {@link Interpolator} object from a resource
*
* @param context Application context used to access resources
* @param id The resource id of the animation to load
* @return The animation object reference by the specified id
* @throws NotFoundException
*/
public static Interpolator loadInterpolator(Context context, int id) throws NotFoundException {
XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
return createInterpolatorFromXml(context, parser);
} catch (XmlPullParserException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} catch (IOException ex) {
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
Integer.toHexString(id));
rnf.initCause(ex);
throw rnf;
} finally {
if (parser != null) parser.close();
}
}
private static Interpolator createInterpolatorFromXml(Context c, XmlPullParser parser)
throws XmlPullParserException, IOException {
Interpolator interpolator = null;
// Make sure we are on a start tag.
int type;
int depth = parser.getDepth();
while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
&& type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
AttributeSet attrs = Xml.asAttributeSet(parser);
String name = parser.getName();
if (name.equals("linearInterpolator")) {
interpolator = new LinearInterpolator(c, attrs);
} else if (name.equals("accelerateInterpolator")) {
interpolator = new AccelerateInterpolator(c, attrs);
} else if (name.equals("decelerateInterpolator")) {
interpolator = new DecelerateInterpolator(c, attrs);
} else if (name.equals("accelerateDecelerateInterpolator")) {
interpolator = new AccelerateDecelerateInterpolator(c, attrs);
} else if (name.equals("cycleInterpolator")) {
interpolator = new CycleInterpolator(c, attrs);
} else if (name.equals("anticipateInterpolator")) {
interpolator = new AnticipateInterpolator(c, attrs);
} else if (name.equals("overshootInterpolator")) {
interpolator = new OvershootInterpolator(c, attrs);
} else if (name.equals("anticipateOvershootInterpolator")) {
interpolator = new AnticipateOvershootInterpolator(c, attrs);
} else if (name.equals("bounceInterpolator")) {
interpolator = new BounceInterpolator(c, attrs);
} else {
throw new RuntimeException("Unknown interpolator name: " + parser.getName());
}
}
return interpolator;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2009 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An interpolator where the change starts backward then flings forward.
*/
public class AnticipateInterpolator implements Interpolator {
private final float mTension;
public AnticipateInterpolator() {
mTension = 2.0f;
}
/**
* @param tension Amount of anticipation. When tension equals 0.0f, there is
* no anticipation and the interpolator becomes a simple
* acceleration interpolator.
*/
public AnticipateInterpolator(float tension) {
mTension = tension;
}
public AnticipateInterpolator(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.AnticipateInterpolator);
mTension =
a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f);
a.recycle();
}
public float getInterpolation(float t) {
// a(t) = t * t * ((tension + 1) * t - tension)
return t * t * ((mTension + 1) * t - mTension);
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2009 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import static com.android.internal.R.styleable.AnticipateOvershootInterpolator_extraTension;
import static com.android.internal.R.styleable.AnticipateOvershootInterpolator_tension;
import static com.android.internal.R.styleable.AnticipateOvershootInterpolator;
/**
* An interpolator where the change starts backward then flings forward and overshoots
* the target value and finally goes back to the final value.
*/
public class AnticipateOvershootInterpolator implements Interpolator {
private final float mTension;
public AnticipateOvershootInterpolator() {
mTension = 2.0f * 1.5f;
}
/**
* @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
* there is no anticipation/overshoot and the interpolator becomes
* a simple acceleration/deceleration interpolator.
*/
public AnticipateOvershootInterpolator(float tension) {
mTension = tension * 1.5f;
}
/**
* @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
* there is no anticipation/overshoot and the interpolator becomes
* a simple acceleration/deceleration interpolator.
* @param extraTension Amount by which to multiply the tension. For instance,
* to get the same overshoot as an OvershootInterpolator with
* a tension of 2.0f, you would use an extraTension of 1.5f.
*/
public AnticipateOvershootInterpolator(float tension, float extraTension) {
mTension = tension * extraTension;
}
public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);
mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *
a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f);
a.recycle();
}
private static float a(float t, float s) {
return t * t * ((s + 1) * t - s);
}
private static float o(float t, float s) {
return t * t * ((s + 1) * t + s);
}
public float getInterpolation(float t) {
// a(t, s) = t * t * ((s + 1) * t - s)
// o(t, s) = t * t * ((s + 1) * t + s)
// f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5
// f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0
if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2009 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An interpolator where the change bounces at the end.
*/
public class BounceInterpolator implements Interpolator {
public BounceInterpolator() {
}
@SuppressWarnings({"UnusedDeclaration"})
public BounceInterpolator(Context context, AttributeSet attrs) {
}
private static float bounce(float t) {
return t * t * 8.0f;
}
public float getInterpolation(float t) {
// _b(t) = t * t * 8
// bs(t) = _b(t) for t < 0.3535
// bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
// bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
// bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
// b(t) = bs(t * 1.1226)
t *= 1.1226f;
if (t < 0.3535f) return bounce(t);
else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
else return bounce(t - 1.0435f) + 0.95f;
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* Repeats the animation for a specified number of cycles. The
* rate of change follows a sinusoidal pattern.
*
*/
public class CycleInterpolator implements Interpolator {
public CycleInterpolator(float cycles) {
mCycles = cycles;
}
public CycleInterpolator(Context context, AttributeSet attrs) {
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);
mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);
a.recycle();
}
public float getInterpolation(float input) {
return (float)(Math.sin(2 * mCycles * Math.PI * input));
}
private float mCycles;
}
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An interpolator where the rate of change starts out quickly and
* and then decelerates.
*
*/
public class DecelerateInterpolator implements Interpolator {
public DecelerateInterpolator() {
}
/**
* Constructor
*
* @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
* an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
* ease-out effect (i.e., it starts even faster and ends evens slower)
*/
public DecelerateInterpolator(float factor) {
mFactor = factor;
}
public DecelerateInterpolator(Context context, AttributeSet attrs) {
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);
mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);
a.recycle();
}
public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return (float)(1.0f - (1.0f - input) * (1.0f - input));
} else {
return (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));
}
}
private float mFactor = 1.0f;
}
@@ -0,0 +1,424 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import android.view.View;
import android.view.ViewGroup;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import java.util.Random;
/**
* A layout animation controller is used to animated a grid layout's children.
*
* While {@link LayoutAnimationController} relies only on the index of the child
* in the view group to compute the animation delay, this class uses both the
* X and Y coordinates of the child within a grid.
*
* In addition, the animation direction can be controlled. The default direction
* is <code>DIRECTION_LEFT_TO_RIGHT | DIRECTION_TOP_TO_BOTTOM</code>. You can
* also set the animation priority to columns or rows. The default priority is
* none.
*
* Information used to compute the animation delay of each child are stored
* in an instance of
* {@link android.view.animation.GridLayoutAnimationController.AnimationParameters},
* itself stored in the {@link android.view.ViewGroup.LayoutParams} of the view.
*
* @see LayoutAnimationController
* @see android.widget.GridView
*
* @attr ref android.R.styleable#GridLayoutAnimation_columnDelay
* @attr ref android.R.styleable#GridLayoutAnimation_rowDelay
* @attr ref android.R.styleable#GridLayoutAnimation_direction
* @attr ref android.R.styleable#GridLayoutAnimation_directionPriority
*/
public class GridLayoutAnimationController extends LayoutAnimationController {
/**
* Animates the children starting from the left of the grid to the right.
*/
public static final int DIRECTION_LEFT_TO_RIGHT = 0x0;
/**
* Animates the children starting from the right of the grid to the left.
*/
public static final int DIRECTION_RIGHT_TO_LEFT = 0x1;
/**
* Animates the children starting from the top of the grid to the bottom.
*/
public static final int DIRECTION_TOP_TO_BOTTOM = 0x0;
/**
* Animates the children starting from the bottom of the grid to the top.
*/
public static final int DIRECTION_BOTTOM_TO_TOP = 0x2;
/**
* Bitmask used to retrieve the horizontal component of the direction.
*/
public static final int DIRECTION_HORIZONTAL_MASK = 0x1;
/**
* Bitmask used to retrieve the vertical component of the direction.
*/
public static final int DIRECTION_VERTICAL_MASK = 0x2;
/**
* Rows and columns are animated at the same time.
*/
public static final int PRIORITY_NONE = 0;
/**
* Columns are animated first.
*/
public static final int PRIORITY_COLUMN = 1;
/**
* Rows are animated first.
*/
public static final int PRIORITY_ROW = 2;
private float mColumnDelay;
private float mRowDelay;
private int mDirection;
private int mDirectionPriority;
/**
* Creates a new grid layout animation controller from external resources.
*
* @param context the Context the view group is running in, through which
* it can access the resources
* @param attrs the attributes of the XML tag that is inflating the
* layout animation controller
*/
public GridLayoutAnimationController(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.GridLayoutAnimation);
Animation.Description d = Animation.Description.parseValue(
a.peekValue(com.android.internal.R.styleable.GridLayoutAnimation_columnDelay));
mColumnDelay = d.value;
d = Animation.Description.parseValue(
a.peekValue(com.android.internal.R.styleable.GridLayoutAnimation_rowDelay));
mRowDelay = d.value;
//noinspection PointlessBitwiseExpression
mDirection = a.getInt(com.android.internal.R.styleable.GridLayoutAnimation_direction,
DIRECTION_LEFT_TO_RIGHT | DIRECTION_TOP_TO_BOTTOM);
mDirectionPriority = a.getInt(com.android.internal.R.styleable.GridLayoutAnimation_directionPriority,
PRIORITY_NONE);
a.recycle();
}
/**
* Creates a new layout animation controller with a delay of 50%
* for both rows and columns and the specified animation.
*
* @param animation the animation to use on each child of the view group
*/
public GridLayoutAnimationController(Animation animation) {
this(animation, 0.5f, 0.5f);
}
/**
* Creates a new layout animation controller with the specified delays
* and the specified animation.
*
* @param animation the animation to use on each child of the view group
* @param columnDelay the delay by which each column animation must be offset
* @param rowDelay the delay by which each row animation must be offset
*/
public GridLayoutAnimationController(Animation animation, float columnDelay, float rowDelay) {
super(animation);
mColumnDelay = columnDelay;
mRowDelay = rowDelay;
}
/**
* Returns the delay by which the children's animation are offset from one
* column to the other. The delay is expressed as a fraction of the
* animation duration.
*
* @return a fraction of the animation duration
*
* @see #setColumnDelay(float)
* @see #getRowDelay()
* @see #setRowDelay(float)
*/
public float getColumnDelay() {
return mColumnDelay;
}
/**
* Sets the delay, as a fraction of the animation duration, by which the
* children's animations are offset from one column to the other.
*
* @param columnDelay a fraction of the animation duration
*
* @see #getColumnDelay()
* @see #getRowDelay()
* @see #setRowDelay(float)
*/
public void setColumnDelay(float columnDelay) {
mColumnDelay = columnDelay;
}
/**
* Returns the delay by which the children's animation are offset from one
* row to the other. The delay is expressed as a fraction of the
* animation duration.
*
* @return a fraction of the animation duration
*
* @see #setRowDelay(float)
* @see #getColumnDelay()
* @see #setColumnDelay(float)
*/
public float getRowDelay() {
return mRowDelay;
}
/**
* Sets the delay, as a fraction of the animation duration, by which the
* children's animations are offset from one row to the other.
*
* @param rowDelay a fraction of the animation duration
*
* @see #getRowDelay()
* @see #getColumnDelay()
* @see #setColumnDelay(float)
*/
public void setRowDelay(float rowDelay) {
mRowDelay = rowDelay;
}
/**
* Returns the direction of the animation. {@link #DIRECTION_HORIZONTAL_MASK}
* and {@link #DIRECTION_VERTICAL_MASK} can be used to retrieve the
* horizontal and vertical components of the direction.
*
* @return the direction of the animation
*
* @see #setDirection(int)
* @see #DIRECTION_BOTTOM_TO_TOP
* @see #DIRECTION_TOP_TO_BOTTOM
* @see #DIRECTION_LEFT_TO_RIGHT
* @see #DIRECTION_RIGHT_TO_LEFT
* @see #DIRECTION_HORIZONTAL_MASK
* @see #DIRECTION_VERTICAL_MASK
*/
public int getDirection() {
return mDirection;
}
/**
* Sets the direction of the animation. The direction is expressed as an
* integer containing a horizontal and vertical component. For instance,
* <code>DIRECTION_BOTTOM_TO_TOP | DIRECTION_RIGHT_TO_LEFT</code>.
*
* @param direction the direction of the animation
*
* @see #getDirection()
* @see #DIRECTION_BOTTOM_TO_TOP
* @see #DIRECTION_TOP_TO_BOTTOM
* @see #DIRECTION_LEFT_TO_RIGHT
* @see #DIRECTION_RIGHT_TO_LEFT
* @see #DIRECTION_HORIZONTAL_MASK
* @see #DIRECTION_VERTICAL_MASK
*/
public void setDirection(int direction) {
mDirection = direction;
}
/**
* Returns the direction priority for the animation. The priority can
* be either {@link #PRIORITY_NONE}, {@link #PRIORITY_COLUMN} or
* {@link #PRIORITY_ROW}.
*
* @return the priority of the animation direction
*
* @see #setDirectionPriority(int)
* @see #PRIORITY_COLUMN
* @see #PRIORITY_NONE
* @see #PRIORITY_ROW
*/
public int getDirectionPriority() {
return mDirectionPriority;
}
/**
* Specifies the direction priority of the animation. For instance,
* {@link #PRIORITY_COLUMN} will give priority to columns: the animation
* will first play on the column, then on the rows.Z
*
* @param directionPriority the direction priority of the animation
*
* @see #getDirectionPriority()
* @see #PRIORITY_COLUMN
* @see #PRIORITY_NONE
* @see #PRIORITY_ROW
*/
public void setDirectionPriority(int directionPriority) {
mDirectionPriority = directionPriority;
}
/**
* {@inheritDoc}
*/
@Override
public boolean willOverlap() {
return mColumnDelay < 1.0f || mRowDelay < 1.0f;
}
/**
* {@inheritDoc}
*/
@Override
protected long getDelayForView(View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
AnimationParameters params = (AnimationParameters) lp.layoutAnimationParameters;
if (params == null) {
return 0;
}
final int column = getTransformedColumnIndex(params);
final int row = getTransformedRowIndex(params);
final int rowsCount = params.rowsCount;
final int columnsCount = params.columnsCount;
final long duration = mAnimation.getDuration();
final float columnDelay = mColumnDelay * duration;
final float rowDelay = mRowDelay * duration;
float totalDelay;
long viewDelay;
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
switch (mDirectionPriority) {
case PRIORITY_COLUMN:
viewDelay = (long) (row * rowDelay + column * rowsCount * rowDelay);
totalDelay = rowsCount * rowDelay + columnsCount * rowsCount * rowDelay;
break;
case PRIORITY_ROW:
viewDelay = (long) (column * columnDelay + row * columnsCount * columnDelay);
totalDelay = columnsCount * columnDelay + rowsCount * columnsCount * columnDelay;
break;
case PRIORITY_NONE:
default:
viewDelay = (long) (column * columnDelay + row * rowDelay);
totalDelay = columnsCount * columnDelay + rowsCount * rowDelay;
break;
}
float normalizedDelay = viewDelay / totalDelay;
normalizedDelay = mInterpolator.getInterpolation(normalizedDelay);
return (long) (normalizedDelay * totalDelay);
}
private int getTransformedColumnIndex(AnimationParameters params) {
int index;
switch (getOrder()) {
case ORDER_REVERSE:
index = params.columnsCount - 1 - params.column;
break;
case ORDER_RANDOM:
if (mRandomizer == null) {
mRandomizer = new Random();
}
index = (int) (params.columnsCount * mRandomizer.nextFloat());
break;
case ORDER_NORMAL:
default:
index = params.column;
break;
}
int direction = mDirection & DIRECTION_HORIZONTAL_MASK;
if (direction == DIRECTION_RIGHT_TO_LEFT) {
index = params.columnsCount - 1 - index;
}
return index;
}
private int getTransformedRowIndex(AnimationParameters params) {
int index;
switch (getOrder()) {
case ORDER_REVERSE:
index = params.rowsCount - 1 - params.row;
break;
case ORDER_RANDOM:
if (mRandomizer == null) {
mRandomizer = new Random();
}
index = (int) (params.rowsCount * mRandomizer.nextFloat());
break;
case ORDER_NORMAL:
default:
index = params.row;
break;
}
int direction = mDirection & DIRECTION_VERTICAL_MASK;
if (direction == DIRECTION_BOTTOM_TO_TOP) {
index = params.rowsCount - 1 - index;
}
return index;
}
/**
* The set of parameters that has to be attached to each view contained in
* the view group animated by the grid layout animation controller. These
* parameters are used to compute the start time of each individual view's
* animation.
*/
public static class AnimationParameters extends
LayoutAnimationController.AnimationParameters {
/**
* The view group's column to which the view belongs.
*/
public int column;
/**
* The view group's row to which the view belongs.
*/
public int row;
/**
* The number of columns in the view's enclosing grid layout.
*/
public int columnsCount;
/**
* The number of rows in the view's enclosing grid layout.
*/
public int rowsCount;
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2006 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 android.view.animation;
/**
* An interpolator defines the rate of change of an animation. This allows
* the basic animation effects (alpha, scale, translate, rotate) to be
* accelerated, decelerated, repeated, etc.
*/
public interface Interpolator {
/**
* Maps a point on the timeline to a multiplier to be applied to the
* transformations of an animation.
*
* @param input A value between 0 and 1.0 indicating our current point
* in the animation where 0 represents the start and 1.0 represents
* the end
* @return The interpolation value. This value can be more than 1.0 for
* Interpolators which overshoot their targets, or less than 0 for
* Interpolators that undershoot their targets.
*/
float getInterpolation(float input);
}
@@ -0,0 +1,435 @@
/*
* Copyright (C) 2007 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import java.util.Random;
/**
* A layout animation controller is used to animated a layout's, or a view
* group's, children. Each child uses the same animation but for every one of
* them, the animation starts at a different time. A layout animation controller
* is used by {@link android.view.ViewGroup} to compute the delay by which each
* child's animation start must be offset. The delay is computed by using
* characteristics of each child, like its index in the view group.
*
* This standard implementation computes the delay by multiplying a fixed
* amount of miliseconds by the index of the child in its parent view group.
* Subclasses are supposed to override
* {@link #getDelayForView(android.view.View)} to implement a different way
* of computing the delay. For instance, a
* {@link android.view.animation.GridLayoutAnimationController} will compute the
* delay based on the column and row indices of the child in its parent view
* group.
*
* Information used to compute the animation delay of each child are stored
* in an instance of
* {@link android.view.animation.LayoutAnimationController.AnimationParameters},
* itself stored in the {@link android.view.ViewGroup.LayoutParams} of the view.
*
* @attr ref android.R.styleable#LayoutAnimation_delay
* @attr ref android.R.styleable#LayoutAnimation_animationOrder
* @attr ref android.R.styleable#LayoutAnimation_interpolator
* @attr ref android.R.styleable#LayoutAnimation_animation
*/
public class LayoutAnimationController {
/**
* Distributes the animation delays in the order in which view were added
* to their view group.
*/
public static final int ORDER_NORMAL = 0;
/**
* Distributes the animation delays in the reverse order in which view were
* added to their view group.
*/
public static final int ORDER_REVERSE = 1;
/**
* Randomly distributes the animation delays.
*/
public static final int ORDER_RANDOM = 2;
/**
* The animation applied on each child of the view group on which this
* layout animation controller is set.
*/
protected Animation mAnimation;
/**
* The randomizer used when the order is set to random. Subclasses should
* use this object to avoid creating their own.
*/
protected Random mRandomizer;
/**
* The interpolator used to interpolate the delays.
*/
protected Interpolator mInterpolator;
private float mDelay;
private int mOrder;
private long mDuration;
private long mMaxDelay;
/**
* Creates a new layout animation controller from external resources.
*
* @param context the Context the view group is running in, through which
* it can access the resources
* @param attrs the attributes of the XML tag that is inflating the
* layout animation controller
*/
public LayoutAnimationController(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.LayoutAnimation);
Animation.Description d = Animation.Description.parseValue(
a.peekValue(com.android.internal.R.styleable.LayoutAnimation_delay));
mDelay = d.value;
mOrder = a.getInt(com.android.internal.R.styleable.LayoutAnimation_animationOrder, ORDER_NORMAL);
int resource = a.getResourceId(com.android.internal.R.styleable.LayoutAnimation_animation, 0);
if (resource > 0) {
setAnimation(context, resource);
}
resource = a.getResourceId(com.android.internal.R.styleable.LayoutAnimation_interpolator, 0);
if (resource > 0) {
setInterpolator(context, resource);
}
a.recycle();
}
/**
* Creates a new layout animation controller with a delay of 50%
* and the specified animation.
*
* @param animation the animation to use on each child of the view group
*/
public LayoutAnimationController(Animation animation) {
this(animation, 0.5f);
}
/**
* Creates a new layout animation controller with the specified delay
* and the specified animation.
*
* @param animation the animation to use on each child of the view group
* @param delay the delay by which each child's animation must be offset
*/
public LayoutAnimationController(Animation animation, float delay) {
mDelay = delay;
setAnimation(animation);
}
/**
* Returns the order used to compute the delay of each child's animation.
*
* @return one of {@link #ORDER_NORMAL}, {@link #ORDER_REVERSE} or
* {@link #ORDER_RANDOM)
*
* @attr ref android.R.styleable#LayoutAnimation_animationOrder
*/
public int getOrder() {
return mOrder;
}
/**
* Sets the order used to compute the delay of each child's animation.
*
* @param order one of {@link #ORDER_NORMAL}, {@link #ORDER_REVERSE} or
* {@link #ORDER_RANDOM}
*
* @attr ref android.R.styleable#LayoutAnimation_animationOrder
*/
public void setOrder(int order) {
mOrder = order;
}
/**
* Sets the animation to be run on each child of the view group on which
* this layout animation controller is .
*
* @param context the context from which the animation must be inflated
* @param resourceID the resource identifier of the animation
*
* @see #setAnimation(Animation)
* @see #getAnimation()
*
* @attr ref android.R.styleable#LayoutAnimation_animation
*/
public void setAnimation(Context context, int resourceID) {
setAnimation(AnimationUtils.loadAnimation(context, resourceID));
}
/**
* Sets the animation to be run on each child of the view group on which
* this layout animation controller is .
*
* @param animation the animation to run on each child of the view group
* @see #setAnimation(android.content.Context, int)
* @see #getAnimation()
*
* @attr ref android.R.styleable#LayoutAnimation_animation
*/
public void setAnimation(Animation animation) {
mAnimation = animation;
mAnimation.setFillBefore(true);
}
/**
* Returns the animation applied to each child of the view group on which
* this controller is set.
*
* @return an {@link android.view.animation.Animation} instance
*
* @see #setAnimation(android.content.Context, int)
* @see #setAnimation(Animation)
*/
public Animation getAnimation() {
return mAnimation;
}
/**
* Sets the interpolator used to interpolate the delays between the
* children.
*
* @param context the context from which the interpolator must be inflated
* @param resourceID the resource identifier of the interpolator
*
* @see #getInterpolator()
* @see #setInterpolator(Interpolator)
*
* @attr ref android.R.styleable#LayoutAnimation_interpolator
*/
public void setInterpolator(Context context, int resourceID) {
setInterpolator(AnimationUtils.loadInterpolator(context, resourceID));
}
/**
* Sets the interpolator used to interpolate the delays between the
* children.
*
* @param interpolator the interpolator
*
* @see #getInterpolator()
* @see #setInterpolator(Interpolator)
*
* @attr ref android.R.styleable#LayoutAnimation_interpolator
*/
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
}
/**
* Returns the interpolator used to interpolate the delays between the
* children.
*
* @return an {@link android.view.animation.Interpolator}
*/
public Interpolator getInterpolator() {
return mInterpolator;
}
/**
* Returns the delay by which the children's animation are offset. The
* delay is expressed as a fraction of the animation duration.
*
* @return a fraction of the animation duration
*
* @see #setDelay(float)
*/
public float getDelay() {
return mDelay;
}
/**
* Sets the delay, as a fraction of the animation duration, by which the
* children's animations are offset. The general formula is:
*
* <pre>
* child animation delay = child index * delay * animation duration
* </pre>
*
* @param delay a fraction of the animation duration
*
* @see #getDelay()
*/
public void setDelay(float delay) {
mDelay = delay;
}
/**
* Indicates whether two children's animations will overlap. Animations
* overlap when the delay is lower than 100% (or 1.0).
*
* @return true if animations will overlap, false otherwise
*/
public boolean willOverlap() {
return mDelay < 1.0f;
}
/**
* Starts the animation.
*/
public void start() {
mDuration = mAnimation.getDuration();
mMaxDelay = Long.MIN_VALUE;
mAnimation.setStartTime(-1);
}
/**
* Returns the animation to be applied to the specified view. The returned
* animation is delayed by an offset computed according to the information
* provided by
* {@link android.view.animation.LayoutAnimationController.AnimationParameters}.
* This method is called by view groups to obtain the animation to set on
* a specific child.
*
* @param view the view to animate
* @return an animation delayed by the number of milliseconds returned by
* {@link #getDelayForView(android.view.View)}
*
* @see #getDelay()
* @see #setDelay(float)
* @see #getDelayForView(android.view.View)
*/
public final Animation getAnimationForView(View view) {
final long delay = getDelayForView(view) + mAnimation.getStartOffset();
mMaxDelay = Math.max(mMaxDelay, delay);
try {
final Animation animation = mAnimation.clone();
animation.setStartOffset(delay);
return animation;
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* Indicates whether the layout animation is over or not. A layout animation
* is considered done when the animation with the longest delay is done.
*
* @return true if all of the children's animations are over, false otherwise
*/
public boolean isDone() {
return AnimationUtils.currentAnimationTimeMillis() >
mAnimation.getStartTime() + mMaxDelay + mDuration;
}
/**
* Returns the amount of milliseconds by which the specified view's
* animation must be delayed or offset. Subclasses should override this
* method to return a suitable value.
*
* This implementation returns <code>child animation delay</code>
* milliseconds where:
*
* <pre>
* child animation delay = child index * delay
* </pre>
*
* The index is retrieved from the
* {@link android.view.animation.LayoutAnimationController.AnimationParameters}
* found in the view's {@link android.view.ViewGroup.LayoutParams}.
*
* @param view the view for which to obtain the animation's delay
* @return a delay in milliseconds
*
* @see #getAnimationForView(android.view.View)
* @see #getDelay()
* @see #getTransformedIndex(android.view.animation.LayoutAnimationController.AnimationParameters)
* @see android.view.ViewGroup.LayoutParams
*/
protected long getDelayForView(View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
AnimationParameters params = lp.layoutAnimationParameters;
if (params == null) {
return 0;
}
final float delay = mDelay * mAnimation.getDuration();
final long viewDelay = (long) (getTransformedIndex(params) * delay);
final float totalDelay = delay * params.count;
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
float normalizedDelay = viewDelay / totalDelay;
normalizedDelay = mInterpolator.getInterpolation(normalizedDelay);
return (long) (normalizedDelay * totalDelay);
}
/**
* Transforms the index stored in
* {@link android.view.animation.LayoutAnimationController.AnimationParameters}
* by the order returned by {@link #getOrder()}. Subclasses should override
* this method to provide additional support for other types of ordering.
* This method should be invoked by
* {@link #getDelayForView(android.view.View)} prior to any computation.
*
* @param params the animation parameters containing the index
* @return a transformed index
*/
protected int getTransformedIndex(AnimationParameters params) {
switch (getOrder()) {
case ORDER_REVERSE:
return params.count - 1 - params.index;
case ORDER_RANDOM:
if (mRandomizer == null) {
mRandomizer = new Random();
}
return (int) (params.count * mRandomizer.nextFloat());
case ORDER_NORMAL:
default:
return params.index;
}
}
/**
* The set of parameters that has to be attached to each view contained in
* the view group animated by the layout animation controller. These
* parameters are used to compute the start time of each individual view's
* animation.
*/
public static class AnimationParameters {
/**
* The number of children in the view group containing the view to which
* these parameters are attached.
*/
public int count;
/**
* The index of the view to which these parameters are attached in its
* containing view group.
*/
public int index;
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.util.AttributeSet;
/**
* An interpolator where the rate of change is constant
*
*/
public class LinearInterpolator implements Interpolator {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
}
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2009 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An interpolator where the change flings forward and overshoots the last value
* then comes back.
*/
public class OvershootInterpolator implements Interpolator {
private final float mTension;
public OvershootInterpolator() {
mTension = 2.0f;
}
/**
* @param tension Amount of overshoot. When tension equals 0.0f, there is
* no overshoot and the interpolator becomes a simple
* deceleration interpolator.
*/
public OvershootInterpolator(float tension) {
mTension = tension;
}
public OvershootInterpolator(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.OvershootInterpolator);
mTension =
a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f);
a.recycle();
}
public float getInterpolation(float t) {
// _o(t) = t * t * ((tension + 1) * t + tension)
// o(t) = _o(t - 1) + 1
t -= 1.0f;
return t * t * ((mTension + 1) * t + mTension) + 1.0f;
}
}
@@ -0,0 +1,165 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An animation that controls the rotation of an object. This rotation takes
* place int the X-Y plane. You can specify the point to use for the center of
* the rotation, where (0,0) is the top left point. If not specified, (0,0) is
* the default rotation point.
*
*/
public class RotateAnimation extends Animation {
private float mFromDegrees;
private float mToDegrees;
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
private float mPivotX;
private float mPivotY;
/**
* Constructor used when a RotateAnimation is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public RotateAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.RotateAnimation);
mFromDegrees = a.getFloat(
com.android.internal.R.styleable.RotateAnimation_fromDegrees, 0.0f);
mToDegrees = a.getFloat(com.android.internal.R.styleable.RotateAnimation_toDegrees, 0.0f);
Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.RotateAnimation_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.RotateAnimation_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
}
/**
* Constructor to use when building a RotateAnimation from code.
* Default pivotX/pivotY point is (0,0).
*
* @param fromDegrees Rotation offset to apply at the start of the
* animation.
*
* @param toDegrees Rotation offset to apply at the end of the animation.
*/
public RotateAnimation(float fromDegrees, float toDegrees) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotX = 0.0f;
mPivotY = 0.0f;
}
/**
* Constructor to use when building a RotateAnimation from code
*
* @param fromDegrees Rotation offset to apply at the start of the
* animation.
*
* @param toDegrees Rotation offset to apply at the end of the animation.
*
* @param pivotX The X coordinate of the point about which the object is
* being rotated, specified as an absolute number where 0 is the left
* edge.
* @param pivotY The Y coordinate of the point about which the object is
* being rotated, specified as an absolute number where 0 is the top
* edge.
*/
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
}
/**
* Constructor to use when building a RotateAnimation from code
*
* @param fromDegrees Rotation offset to apply at the start of the
* animation.
*
* @param toDegrees Rotation offset to apply at the end of the animation.
*
* @param pivotXType Specifies how pivotXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotXValue The X coordinate of the point about which the object
* is being rotated, specified as an absolute number where 0 is the
* left edge. This value can either be an absolute number if
* pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
* otherwise.
* @param pivotYType Specifies how pivotYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotYValue The Y coordinate of the point about which the object
* is being rotated, specified as an absolute number where 0 is the
* top edge. This value can either be an absolute number if
* pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
* otherwise.
*/
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
if (mPivotX == 0.0f && mPivotY == 0.0f) {
t.getMatrix().setRotate(degrees);
} else {
t.getMatrix().setRotate(degrees, mPivotX, mPivotY);
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
}
@@ -0,0 +1,186 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An animation that controls the scale of an object. You can specify the point
* to use for the center of scaling.
*
*/
public class ScaleAnimation extends Animation {
private float mFromX;
private float mToX;
private float mFromY;
private float mToY;
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
private float mPivotX;
private float mPivotY;
/**
* Constructor used when a ScaleAnimation is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public ScaleAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ScaleAnimation);
mFromX = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_fromXScale, 0.0f);
mToX = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_toXScale, 0.0f);
mFromY = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_fromYScale, 0.0f);
mToY = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_toYScale, 0.0f);
Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
}
/**
* Constructor to use when building a ScaleAnimation from code
*
* @param fromX Horizontal scaling factor to apply at the start of the
* animation
* @param toX Horizontal scaling factor to apply at the end of the animation
* @param fromY Vertical scaling factor to apply at the start of the
* animation
* @param toY Vertical scaling factor to apply at the end of the animation
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotX = 0;
mPivotY = 0;
}
/**
* Constructor to use when building a ScaleAnimation from code
*
* @param fromX Horizontal scaling factor to apply at the start of the
* animation
* @param toX Horizontal scaling factor to apply at the end of the animation
* @param fromY Vertical scaling factor to apply at the start of the
* animation
* @param toY Vertical scaling factor to apply at the end of the animation
* @param pivotX The X coordinate of the point about which the object is
* being scaled, specified as an absolute number where 0 is the left
* edge. (This point remains fixed while the object changes size.)
* @param pivotY The Y coordinate of the point about which the object is
* being scaled, specified as an absolute number where 0 is the top
* edge. (This point remains fixed while the object changes size.)
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY) {
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
}
/**
* Constructor to use when building a ScaleAnimation from code
*
* @param fromX Horizontal scaling factor to apply at the start of the
* animation
* @param toX Horizontal scaling factor to apply at the end of the animation
* @param fromY Vertical scaling factor to apply at the start of the
* animation
* @param toY Vertical scaling factor to apply at the end of the animation
* @param pivotXType Specifies how pivotXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotXValue The X coordinate of the point about which the object
* is being scaled, specified as an absolute number where 0 is the
* left edge. (This point remains fixed while the object changes
* size.) This value can either be an absolute number if pivotXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param pivotYType Specifies how pivotYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotYValue The Y coordinate of the point about which the object
* is being scaled, specified as an absolute number where 0 is the
* top edge. (This point remains fixed while the object changes
* size.) This value can either be an absolute number if pivotYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float sx = 1.0f;
float sy = 1.0f;
if (mFromX != 1.0f || mToX != 1.0f) {
sx = mFromX + ((mToX - mFromX) * interpolatedTime);
}
if (mFromY != 1.0f || mToY != 1.0f) {
sy = mFromY + ((mToY - mFromY) * interpolatedTime);
}
if (mPivotX == 0 && mPivotY == 0) {
t.getMatrix().setScale(sx, sy);
} else {
t.getMatrix().setScale(sx, sy, mPivotX, mPivotY);
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
}
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.graphics.Matrix;
import java.io.PrintWriter;
/**
* Defines the transformation to be applied at
* one point in time of an Animation.
*
*/
public class Transformation {
/**
* Indicates a transformation that has no effect (alpha = 1 and identity matrix.)
*/
public static int TYPE_IDENTITY = 0x0;
/**
* Indicates a transformation that applies an alpha only (uses an identity matrix.)
*/
public static int TYPE_ALPHA = 0x1;
/**
* Indicates a transformation that applies a matrix only (alpha = 1.)
*/
public static int TYPE_MATRIX = 0x2;
/**
* Indicates a transformation that applies an alpha and a matrix.
*/
public static int TYPE_BOTH = TYPE_ALPHA | TYPE_MATRIX;
protected Matrix mMatrix;
protected float mAlpha;
protected int mTransformationType;
/**
* Creates a new transformation with alpha = 1 and the identity matrix.
*/
public Transformation() {
clear();
}
/**
* Reset the transformation to a state that leaves the object
* being animated in an unmodified state. The transformation type is
* {@link #TYPE_BOTH} by default.
*/
public void clear() {
if (mMatrix == null) {
mMatrix = new Matrix();
} else {
mMatrix.reset();
}
mAlpha = 1.0f;
mTransformationType = TYPE_BOTH;
}
/**
* Indicates the nature of this transformation.
*
* @return {@link #TYPE_ALPHA}, {@link #TYPE_MATRIX},
* {@link #TYPE_BOTH} or {@link #TYPE_IDENTITY}.
*/
public int getTransformationType() {
return mTransformationType;
}
/**
* Sets the transformation type.
*
* @param transformationType One of {@link #TYPE_ALPHA},
* {@link #TYPE_MATRIX}, {@link #TYPE_BOTH} or
* {@link #TYPE_IDENTITY}.
*/
public void setTransformationType(int transformationType) {
mTransformationType = transformationType;
}
/**
* Clones the specified transformation.
*
* @param t The transformation to clone.
*/
public void set(Transformation t) {
mAlpha = t.getAlpha();
mMatrix.set(t.getMatrix());
mTransformationType = t.getTransformationType();
}
/**
* Apply this Transformation to an existing Transformation, e.g. apply
* a scale effect to something that has already been rotated.
* @param t
*/
public void compose(Transformation t) {
mAlpha *= t.getAlpha();
mMatrix.preConcat(t.getMatrix());
}
/**
* @return The 3x3 Matrix representing the trnasformation to apply to the
* coordinates of the object being animated
*/
public Matrix getMatrix() {
return mMatrix;
}
/**
* Sets the degree of transparency
* @param alpha 1.0 means fully opaqe and 0.0 means fully transparent
*/
public void setAlpha(float alpha) {
mAlpha = alpha;
}
/**
* @return The degree of transparency
*/
public float getAlpha() {
return mAlpha;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(64);
sb.append("Transformation");
toShortString(sb);
return sb.toString();
}
/**
* Return a string representation of the transformation in a compact form.
*/
public String toShortString() {
StringBuilder sb = new StringBuilder(64);
toShortString(sb);
return sb.toString();
}
/**
* @hide
*/
public void toShortString(StringBuilder sb) {
sb.append("{alpha="); sb.append(mAlpha);
sb.append(" matrix="); mMatrix.toShortString(sb);
sb.append('}');
}
/**
* Print short string, to optimize dumping.
* @hide
*/
public void printShortString(PrintWriter pw) {
pw.print("{alpha="); pw.print(mAlpha);
pw.print(" matrix=");
mMatrix.printShortString(pw);
pw.print('}');
}
}
@@ -0,0 +1,170 @@
/*
* Copyright (C) 2006 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 android.view.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
/**
* An animation that controls the position of an object. See the
* {@link android.view.animation full package} description for details and
* sample code.
*
*/
public class TranslateAnimation extends Animation {
private int mFromXType = ABSOLUTE;
private int mToXType = ABSOLUTE;
private int mFromYType = ABSOLUTE;
private int mToYType = ABSOLUTE;
private float mFromXValue = 0.0f;
private float mToXValue = 0.0f;
private float mFromYValue = 0.0f;
private float mToYValue = 0.0f;
private float mFromXDelta;
private float mToXDelta;
private float mFromYDelta;
private float mToYDelta;
/**
* Constructor used when a TranslateAnimation is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public TranslateAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.TranslateAnimation);
Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromXDelta));
mFromXType = d.type;
mFromXValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toXDelta));
mToXType = d.type;
mToXValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromYDelta));
mFromYType = d.type;
mFromYValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toYDelta));
mToYType = d.type;
mToYValue = d.value;
a.recycle();
}
/**
* Constructor to use when building a TranslateAnimation from code
*
* @param fromXDelta Change in X coordinate to apply at the start of the
* animation
* @param toXDelta Change in X coordinate to apply at the end of the
* animation
* @param fromYDelta Change in Y coordinate to apply at the start of the
* animation
* @param toYDelta Change in Y coordinate to apply at the end of the
* animation
*/
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
mFromXValue = fromXDelta;
mToXValue = toXDelta;
mFromYValue = fromYDelta;
mToYValue = toYDelta;
mFromXType = ABSOLUTE;
mToXType = ABSOLUTE;
mFromYType = ABSOLUTE;
mToYType = ABSOLUTE;
}
/**
* Constructor to use when building a TranslateAnimation from code
*
* @param fromXType Specifies how fromXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromXValue Change in X coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toXType Specifies how toXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toXValue Change in X coordinate to apply at the end of the
* animation. This value can either be an absolute number if toXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param fromYType Specifies how fromYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromYValue Change in Y coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toYType Specifies how toYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toYValue Change in Y coordinate to apply at the end of the
* animation. This value can either be an absolute number if toYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
*/
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue) {
mFromXValue = fromXValue;
mToXValue = toXValue;
mFromYValue = fromYValue;
mToYValue = toYValue;
mFromXType = fromXType;
mToXType = toXType;
mFromYType = fromYType;
mToYType = toYType;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
}
}
+20
View File
@@ -0,0 +1,20 @@
<html>
<body>
<p>Provides classes that handle tweened animations.</p>
<p>Android provides two mechanisms
that you can use to create simple animations: <strong>tweened
animation</strong>, in which you tell Android to perform a series of simple
transformations (position, size, rotation, and so on) to the content of a
View; and <strong>frame-by-frame animation</strong>, which loads a series of Drawable resources
one after the other. Both animation types can be used in any View object
to provide simple rotating timers, activity icons, and other useful UI elements.
Tweened animation is handled by this package (android.view.animation); frame-by-frame animation is
handled by the {@link android.graphics.drawable.AnimationDrawable} class.
</p>
<p>For more information on creating tweened or frame-by-frame animations, read the discussion in the
<a href="{@docRoot}guide/topics/graphics/2d-graphics.html#tween-animation">2D Graphics</a>
Dev Guide.</p>
</body>
</html>