更新:車輪を再発明した可能性があることに気付きました。キーフレームの指定をご覧ください。
この種のものが何も利用できないことを見るのは衝撃的です。とにかく、実行時にパスの長さを計算したくない場合は、パスに重みを割り当てる機能を追加できました。アイデアは、パスに重みを割り当て、アニメーションを実行して、それが問題ないと感じたら実行し、それ以外の場合は、各パスに割り当てられた重みを増減するだけです。
次のコードは、質問で指摘した公式の Android サンプルから変更されたコードです。
// Set up the path we're animating along
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0).setWeight(0);
path.lineTo(0, 300).setWeight(30);// assign arbitrary weight
path.curveTo(100, 0, 300, 900, 400, 500).setWeight(70);// assign arbitrary weight
final PathPoint[] points = path.getPoints().toArray(new PathPoint[] {});
mFirstKeyframe = points[0];
final int numFrames = points.length;
final PathEvaluator pathEvaluator = new PathEvaluator();
final ValueAnimator anim = ValueAnimator.ofInt(0, 1);// dummy values
anim.setDuration(1000);
anim.setInterpolator(new LinearInterpolator());
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = animation.getAnimatedFraction();
// Special-case optimization for the common case of only two
// keyframes
if (numFrames == 2) {
PathPoint nextPoint = pathEvaluator.evaluate(fraction,
points[0], points[1]);
setButtonLoc(nextPoint);
} else {
PathPoint prevKeyframe = mFirstKeyframe;
for (int i = 1; i < numFrames; ++i) {
PathPoint nextKeyframe = points[i];
if (fraction < nextKeyframe.getFraction()) {
final float prevFraction = prevKeyframe
.getFraction();
float intervalFraction = (fraction - prevFraction)
/ (nextKeyframe.getFraction() - prevFraction);
PathPoint nextPoint = pathEvaluator.evaluate(
intervalFraction, prevKeyframe,
nextKeyframe);
setButtonLoc(nextPoint);
break;
}
prevKeyframe = nextKeyframe;
}
}
}
});
以上です !!!。
もちろん、他のクラスも変更しましたが、大きなものは何も追加されていません。たとえば、PathPoint
これを追加しました:
float mWeight;
float mFraction;
public void setWeight(float weight) {
mWeight = weight;
}
public float getWeight() {
return mWeight;
}
public void setFraction(float fraction) {
mFraction = fraction;
}
public float getFraction() {
return mFraction;
}
AnimatorPath
私はこのようにメソッドを変更しgetPoints()
ました:
public Collection<PathPoint> getPoints() {
// calculate fractions
float totalWeight = 0.0F;
for (PathPoint p : mPoints) {
totalWeight += p.getWeight();
}
float lastWeight = 0F;
for (PathPoint p : mPoints) {
p.setFraction(lastWeight = lastWeight + p.getWeight() / totalWeight);
}
return mPoints;
}
そして、それはほとんどそれです。ああ、読みやすくするために に Builder パターンを追加したAnimatorPath
ので、3 つのメソッドはすべて次のように変更されました。
public PathPoint moveTo(float x, float y) {// same for lineTo and curveTo method
PathPoint p = PathPoint.moveTo(x, y);
mPoints.add(p);
return p;
}
注:Interpolator
0 未満または 1 より大きい分数を与える sを処理するには (例: AnticipateOvershootInterpolator
)com.nineoldandroids.animation.KeyframeSet.getValue(float fraction)
メソッドを参照し、 でロジックを実装しonAnimationUpdate(ValueAnimator animation)
ます。