2

ボタンクリックアニメーションを作成しようとしています。たとえば、ボタンを押すとボタンが少し縮小し、離すと元に戻ります。タップするだけで、プレスとリリースが連動します。

onTouchListener と、2 つの XML 定義の AnimatorSet (プレス用とリリース用) をセットアップしました。でプレスを実行し、またはACTION_DOWNでリリースを実行しました。これは、ボタンを押したままにしてから少し離すと正常に機能します。しかし、すばやくタップすると、プレス 1 が完了する前にリリース アニメーションがトリガーされ、結果としてアニメーションがまったく発生しないことがよくあります。ACTION_UPACTION_CANCEL

AnimatorSet のシーケンシャル機能を使用して、既に実行されている可能性のあるプレス アニメーションの最後にリリース アニメーションを貼り付けたいと思っていましたが、うまくいきませんでした。コールバックを使って何かを仕掛けることができると確信していますが、それは面倒です。

ここで最善のアプローチは何ですか?ありがとう!

4

2 に答える 2

5

アニメーションをバッファリングし、必要に応じてキューで実行するサンプルの Button クラスを作成しました。

public class AnimationButton extends Button 
{
    private List<Animation> mAnimationBuffer = new ArrayList<Animation>();;
    private boolean mIsAnimating;

    public AnimationButton(Context context) 
    {
        super(context);

    }

    public AnimationButton(Context context, AttributeSet attrs) 
    {
        super(context, attrs);

    }

    public AnimationButton(Context context, AttributeSet attrs, int defStyle) 
    {
        super(context, attrs, defStyle);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) 
    {
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            generateAnimation(1, 0.75f);
            triggerNextAnimation();
        }
        else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP)
        {
            generateAnimation(0.75f, 1);
            triggerNextAnimation();
        }

        return super.onTouchEvent(event);
    }

    private void generateAnimation(float from, float to)
    {
        ScaleAnimation scaleAnimation = new ScaleAnimation(from, to, from, to);
        scaleAnimation.setFillAfter(true);
        scaleAnimation.setDuration(500);
        scaleAnimation.setAnimationListener(new ScaleAnimation.AnimationListener() 
        {       
            @Override
            public void onAnimationStart(Animation animation) { }

            @Override
            public void onAnimationRepeat(Animation animation) { }

            @Override
            public void onAnimationEnd(Animation animation) 
            {               
                mIsAnimating = false;
                triggerNextAnimation();
            }
        });

        mAnimationBuffer.add(scaleAnimation);
    }

    private void triggerNextAnimation()
    {
        if (mAnimationBuffer.size() > 0 && !mIsAnimating)
        {
            mIsAnimating = true;
            Animation currAnimation = mAnimationBuffer.get(0);
            mAnimationBuffer.remove(0);

            startAnimation(currAnimation);
        }
    }

}

お役に立てれば :)

于 2013-10-09T02:00:52.853 に答える