2

こんにちは私はAnimatorSetとValueAnimatorを使用してビューに複数のアニメーションを適用しています。

ユーザーがビューに触れると、連続するアニメーションがビューに適用されます。これは、ユーザーがビュー上で指を動かしているときに「ズーム効果」を持たせるために行います。

ビューはカスタムギャラリーです。

アニメーションのコードは次のとおりです。

private void createAnim(final View v) {
    animating = true;
    if (D)
        Log.i(TAG, "sarting animation");
    try {
        v.clearAnimation();
        v.getAnimation().reset();
    } catch (Exception e) {

    }
    
    set = new AnimatorSet();
    
    set.addListener(new AnimatorListener() {

        @Override
        public void onAnimationStart(Animator animation) {

            
        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if (D)
                Log.i(TAG, "Animation ended");
            animating = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            animating = false;
            if (D)
                Log.i(TAG, "Animation cancelled");

        }
    });     

    set.setDuration(100);

    ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor);
    ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor);

    animationList.add(v1);
    animationList.add(v2);
    set.playTogether(v1, v2);

set.start()
}

私はonTouchListenerを持っており、アクション移動時にこのメソッドを連続して呼び出し、mScaleFactorを増減します。

ユーザーが指を離すと、ビューを前の状態に戻したいのですが、ビューに適用されていないかのように、適用されたすべてのアニメーションを消去することを意味します。問題は、1つのアニメーションで簡単にそれを実行できることですが、そのような多くのアニメーションでは、正しい方法を見つけることができません。これが私が試したことです:

-アニメーションをArrayListに追加し、それぞれに+100の遅延を追加してanimation.reverse()を実行すると、次々に実行されますが、最終結果は以前とまったく同じではないように見えます。アニメーション。

v.clearAnimation(); 最後のアニメーションのみをキャンセルしますv.getAnimation()。reset(); 同じことが最後の/アクティブなアニメーションでのみ機能します。アニメーションが開始される前のビューを元に戻す方法はありますか?どうもありがとう

4

1 に答える 1

5

AnimatorSet「逆」の方法がないという理由だけで、の効果を元に戻すのは難しい場合があります。この場合の最も簡単な方法は、おそらくAnimatorSet元の方法とは逆の方法です。ここでの問題はAnimatorListener、同期がとれていない可能性があることです。このようにしてブール値を維持したい場合は、セマフォのように実装する必要があります。

public static class AnimatorTracker implements AnimatorListener{
    int counter;

    public AnimatorTracker() {
      counter = 0;
    }

    public boolean isAnimating() {
      return counter == 0;
    }

    @Override
    public void onAnimationStart(Animator animation) {
      counter++;
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
      counter--;
    }

    @Override
    public void onAnimationCancel(Animator animation) {
      // Canceling an animation invokes onAnimationEnd, so nothing needs to be done.
    }
  }

次に、今行ったのと同じ方法でセットを作成します。

AnimatorTracker tracker = new AnimatorTracker(); // or make it a global reference
AnimatorSet set = new AnimatorSet();
AnimatorSet reverseSet = new AnimatorSet();

ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor);
ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor);
ValueAnimator reverseV1 = ObjectAnimator.ofFloat(v, "scaleX", 1.0f);
ValueAnimator reverseV2 = ObjectAnimator.ofFloat(v, "scaleY", 1.0f);


set.addListener(tracker);
set.setDuration(100);
set.playTogether(v1, v2);

reverseSet.addListener(tracker);
reverseSet.setDuration(100);
reverseSet.playTogether(reverseV1, reverseV2);

set.start()前方にアニメートしたいときに電話してください。reverseSet.start()アニメートしたいときに電話してください。

于 2012-08-16T12:57:43.927 に答える