教你實現別人家的動畫2

上一篇文章我們簡單分析實現了Yalantis公司的SliderMenu,這次我們還是來寫寫它家的另一個動畫
ContextMenu
github地址:https://github.com/Yalantis/Context-Menu.Android
效果如下
這裏寫圖片描述

話不多說,同樣我們來簡單分析下

  • 首先還是2個動畫集合 :顯示動畫集合和隱藏動畫集合
  • 顯示動畫裏面有2種動畫,一種是第一個沿Y軸打開,第二種其他的沿X軸打開
  • 隱藏動畫裏面比較特別,要觀察仔細就可以發現裏面有三種不同的動畫,第一種前半部分是沿X軸向下收,第二種就是中間那個(也就是點擊的那個)沿Y軸向裏收,第三種下半部分是沿X軸向上收,和上半部分相反,還有一個重要的是上半部分和下半部分是同時播放 播放完後再執行中間那個

額 大家看明白了麼 要多看幾遍 仔細觀察分析 複雜的動畫其實都是由簡單的動畫組成的,不要被嚇倒。
ok ,開始動手了,佈局爲了簡單還是沿用上一篇文章的佈局 如下
這裏寫圖片描述

好的開始寫各個不同的動畫了
首先我們來寫顯示動畫集合裏面的2種動畫

 //Y show 打開-第一個
    private ObjectAnimator createFlipYShowAnim(final View target) {
        target.setPivotX(0);
        target.setPivotY(target.getHeight() / 2);
        ObjectAnimator invisToVis = ObjectAnimator.ofFloat(target, "rotationY", 90f, 0f);
        invisToVis.setDuration(DURATION);
        invisToVis.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                target.setVisibility(View.VISIBLE);
            }
        });
        return invisToVis;
    }
 //x show 打開-下半部(第一個之外的)
    private ObjectAnimator createFlipXShowAnim(final View target) {
        target.setPivotX(target.getWidth() / 2);
        target.setPivotY(0);
        ObjectAnimator invisToVis = ObjectAnimator.ofFloat(target, "rotationX", -90f, 0f);
        invisToVis.setDuration(DURATION);
        invisToVis.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                target.setVisibility(View.VISIBLE);
            }
        });
        return invisToVis;
    }

再來寫隱藏的三種動畫

//x hidden before 隱藏-上半部
    private ObjectAnimator createFlipXBeforeHiddenAnim(final View target, int i) {
        target.setPivotX(target.getWidth() / 2);
        target.setPivotY(target.getHeight());
        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationX", 0f, 90f);
        if (i == 0) {
            visToInvis.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    //播放完後恢復位置
                    target.setVisibility(View.INVISIBLE);
                    target.setPivotX(target.getWidth() / 2);
                    target.setPivotY(target.getHeight());
                    ObjectAnimator openAnim = ObjectAnimator.ofFloat(target, "rotationX", 90f, 0f);
                    openAnim.start();
                }
            });
        }
        visToInvis.setDuration(DURATION);
        return visToInvis;
    }
//Y hidden 隱藏-中間(點擊部分)
    private ObjectAnimator createFlipYHiddenAnim(final View target) {
        target.setPivotX(0);
        target.setPivotY(target.getHeight() / 2);
        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationY", 0f, 90f);
        visToInvis.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                target.setVisibility(View.INVISIBLE);
                target.setPivotX(0);
                target.setPivotY(target.getHeight() / 2);
                ObjectAnimator openAnim = ObjectAnimator.ofFloat(target, "rotationY", 90f, 0f);
                openAnim.start();
            }
        });
        visToInvis.setDuration(DURATION);
        return visToInvis;
    }
//x hidden after 隱藏-下半部
    private ObjectAnimator createFlipXAfterHiddenAnim(View target) {
        target.setPivotX(target.getWidth() / 2);
        target.setPivotY(0);
        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationX", 0f, -90f);
        visToInvis.setDuration(DURATION);
        return visToInvis;
    }

註釋都加上了 沒有什麼特別的地方

現在我們開始把它們加到動畫集合裏面
顯示動畫集合

  private AnimatorSet initShowAnim(ViewGroup parent) {
        ArrayList<Animator> visAnimList = new ArrayList<Animator>();
        for (int i = 0; i < parent.getChildCount(); i++) {
            ObjectAnimator itemAnim = null;
            if (i == 0) {//第一個動畫
                itemAnim = createFlipYShowAnim(parent.getChildAt(i));
            } else {
                itemAnim = createFlipXShowAnim(parent.getChildAt(i));
            }
            visAnimList.add(itemAnim);
        }
        AnimatorSet anim = new AnimatorSet();
        anim.playSequentially(visAnimList);
        return anim;
    }

隱藏動畫
隱藏動畫稍微多點 因爲它有多種動畫 代碼裏面的MIDDLE我們假定爲3 就是點擊的哪個按鈕位置

private Animator initHiddenAnim(ViewGroup parent) {
        AnimatorSet beforAnim = new AnimatorSet();
        AnimatorSet middleAnim = new AnimatorSet();
        AnimatorSet afterAnim = new AnimatorSet();
        ArrayList<Animator> beforeAnimList = new ArrayList<Animator>();
        ArrayList<Animator> middleAnimList = new ArrayList<Animator>();
        ArrayList<Animator> afterAnimList = new ArrayList<Animator>();
        for (int i = 0; i < parent.getChildCount(); i++) {
            if (i < MIDDLE) {
                ObjectAnimator itemAnim = createFlipXBeforeHiddenAnim(parent.getChildAt(i), i);
                beforeAnimList.add(itemAnim);
            } else if (i > MIDDLE) {
                ObjectAnimator itemAnim = createFlipXAfterHiddenAnim(parent.getChildAt(i));
                afterAnimList.add(itemAnim);
            } else {
                ObjectAnimator itemAnim = createFlipYHiddenAnim(parent.getChildAt(i));
                middleAnimList.add(itemAnim);
            }
        }
        beforAnim.playSequentially(beforeAnimList);
        middleAnim.playSequentially(middleAnimList);
        Collections.reverse(afterAnimList);
        afterAnim.playSequentially(afterAnimList);
        AnimatorSet anim = new AnimatorSet();
        anim.play(beforAnim).with(afterAnim).before(middleAnim);
        return anim;
    }

點擊執行直接調用上面的方法了

initShowAnim(parent).start();//顯示動畫執行
initHiddenAnim(parent).start();//隱藏動畫執行

爲了理解簡單 上面的代碼並沒有嚴格規範和優化,大家根據自己習慣自行調整了
ok 我們看一下最後的效果了 ( ps:錄屏真是挺麻煩的 不知道有什麼簡單好用工具推薦)
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章