天天看點

Android用Animation實作完整的抛物線效果

最近需求要做一個小球上升再下降的抛物線運動,類似太陽東升西落的動畫。

在網上找了好久,好多的抛物線都是平抛,用于購物車添加效果。

于是自己動手,做了一個完整的向上抛物線的動畫。

首先要區分兩個概念,一個是VIew的坐标系,如下圖(來自網絡)

Android用Animation實作完整的抛物線效果

另外一個就是Animation動畫的坐标,最開始,我以為動畫是在View坐标系上進行的。研究之後才發現,Animation有自己的坐标,跟View的坐标沒有關系。如下(圖檔來源于網絡),動畫的坐标原點是VIew動畫開始的起點(左上角)

Android用Animation實作完整的抛物線效果

是以要實作完整的抛物線運動,首先要通過計算,算出抛物線的起點、頂點、終點。通過設定動畫參數就可以了

Android用Animation實作完整的抛物線效果

首先确定抛物線的原點(TextView的中心),然後在通過對這個坐标在X軸Y軸上加減得到起點。頂點、終點。

private void initLocation(TextView textView) {
        //擷取抛物線原點坐标
        int[] point_location = new int[2];
        textView.getLocationInWindow(point_location);
        int pointX = point_location[0] - textView.getWidth() / 2;
        int pointY = point_location[1] - textView.getHeight() / 2;

        //擷取抛物線起點坐标
        startX = pointX - 500;
        startY = pointY;
        
       //擷取抛物線頂點坐标
        topX = pointX;
        topY = pointY - 800;

        //擷取抛物線終點坐标
        endX = pointX + 500;
        endY = pointY;
    }
           

最後就可以做動畫啦,動畫分為上升和下降兩個部分

/**
     * 抛物線 上升動畫
     */
    @TargetApi(11)
    public void playUpAnimation() {
        initLocation(tvPoint);
        moveingIV = (ImageView) getLayoutInflater().inflate(R.layout.animator_image, null);
        anim_mask_layout.addView(moveingIV);//把動畫圖檔添加到動畫層

        addViewToAnimLayout(moveingIV, startX, startY);

        //抛物線動畫,原理:兩個位移動畫,一個橫向勻速移動,一個縱向變速移動,兩個動畫同時執行,就有了抛物線的效果。
        ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(moveingIV, "translationX", 0, topX - startX);
        translateAnimationX.setDuration(800);
        translateAnimationX.setInterpolator(new AccelerateInterpolator());

        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(moveingIV, "translationY", 0, topY - startY);
        translateAnimationY.setDuration(800);
        translateAnimationY.setInterpolator(new LinearInterpolator());

        AnimatorSet animatorSet = new AnimatorSet();//設定動畫播放順序
        animatorSet.play(translateAnimationX).with(translateAnimationY);
        animatorSet.start();
    }

     /**
     * 抛物線 下降動畫
     */
    @TargetApi(11)
    public void playDownAnimation() {

        //抛物線動畫,原理:兩個位移動畫,一個橫向勻速移動,一個縱向變速移動,兩個動畫同時執行,就有了抛物線的效果。
        ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(moveingIV, "translationX", topX - startX, endX - startX);
        translateAnimationX.setDuration(800);
        translateAnimationX.setInterpolator(new LinearInterpolator());

        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(moveingIV, "translationY", topY - startY, 0);
        translateAnimationY.setDuration(800);
        translateAnimationY.setInterpolator(new AccelerateInterpolator());
        AnimatorSet animatorSet = new AnimatorSet();//設定動畫播放順序
        animatorSet.play(translateAnimationX).with(translateAnimationY);
        translateAnimationY.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                anim_mask_layout.removeView(moveingIV); //動畫結束後移除動畫圖檔
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        animatorSet.start();
    }
           

完整DEMO

https://download.csdn.net/download/y280903468/11970396