Poniżej pełni funkcjonujący kod, który będzie animować wzdłuż zakrzywionej ścieżki wyznaczonej przez trzy punkty. Punkt jest po prostu klasą trzymającą wartość xi wartość y (choć można ją łatwo rozszerzyć dla większej ilości wymiarów).
Wszystkie zmienne m są pobierane z TranslateAnimation i używane w podobny sposób, więc powinieneś być w stanie porównać to z kodem TranslateAnimation względnie eaSILY, jeśli coś nie ma sensu.
Wywołania funkcji resolveSize in initialize oznaczają, że możesz określić początek, koniec i promień łuku za pomocą dowolnego z typów animacji (ABSOLUTE, RELATIVE_TO_SELF, RELATIVE_TO_PARENT), tak jak w przypadku zwykłej funkcji TranslateAnimation.
calcBezier oblicza kwadratową krzywą Beziera pobraną bezpośrednio z Wikipedia. Krzywa Beziera ma umożliwiać płynne skalowanie i jest powszechna w grafice (a także używana w klasie Path systemu Android).
Rzeczywisty ruch odbywa się w applyTransformation. interpolatedTime daje wartość między 0 a 1, która wzrasta nieliniowo w zależności od dostarczonego interpolatora. dx i dy są rzeczywistymi punktami x i y wzdłuż krzywej dla danego czasu.
Jedynym ograniczeniem tej klasy jest to, że największa zmiana y zawsze występuje w środku krzywej (zobacz obliczenia dla średniego X w inicjalizacji). Można jednak łatwo zmodyfikować, na przykład, nadać określony punkt na krzywej, w której powinien wystąpić punkt wysoki, jeśli chcemy uzyskać niesymetryczną krzywą.
Patrząc na kod androida dla TranslateAnimation był szczególnie pomocny.Zobacz: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/android/view/animation/TranslateAnimation.java#TranslateAnimation
public class ArcTranslate extends Animation {
private Point start;
private Point end;
private Point middle;
private final float mFromXValue;
private final float mToXValue;
private final float mYValue;
private final int mFromXType;
private final int mToXType;
private final int mYType;
/**
* A translation along an arc defined by three points and a Bezier Curve
*
* @param duration - the time in ms it will take for the translation to complete
* @param fromXType - 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
* @param toXType - 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
* @param yType - One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.
* @param yValue - Change in Y coordinate to apply at the middle of the animation (the radius of the arc)
*/
public ArcTranslate(long duration, int fromXType, float fromXValue,
int toXType, float toXValue, int yType, float yValue){
setDuration(duration);
mFromXValue = fromXValue;
mToXValue = toXValue;
mYValue = yValue;
mFromXType = fromXType;
mToXType = toXType;
mYType = yType;
}
/** Calculate the position on a quadratic bezier curve given three points
* and the percentage of time passed.
* from http://en.wikipedia.org/wiki/B%C3%A9zier_curve
* @param interpolatedTime - the fraction of the duration that has passed where 0<=time<=1
* @param p0 - a single dimension of the starting point
* @param p1 - a single dimension of the middle point
* @param p2 - a single dimension of the ending point
*/
private long calcBezier(float interpolatedTime, float p0, float p1, float p2){
return Math.round((Math.pow((1 - interpolatedTime), 2) * p0)
+ (2 * (1 - interpolatedTime) * interpolatedTime * p1)
+ (Math.pow(interpolatedTime, 2) * p2));
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = calcBezier(interpolatedTime, start.x, middle.x, end.x);
float dy = calcBezier(interpolatedTime, start.y, middle.y, end.y);
t.getMatrix().setTranslate(dx, dy);
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
float startX = resolveSize(mFromXType, mFromXValue, width, parentWidth);
float endX = resolveSize(mToXType, mToXValue, width, parentWidth);
float middleY = resolveSize(mYType, mYValue, width, parentWidth);
float middleX = startX + ((endX-startX)/2);
start = new Point(startX, 0);
end = new Point(endX, 0);
middle = new Point(middleX, middleY);
}
}
Zobacz tę odpowiedź: [Przygotowanie krzywej tłumaczyć animację w Android] (http://stackoverflow.com/questions/8354441/how-to-prepare-curve-translate-animation-for- android/27948353 # 27948353) – Sheharyar