教你实现别人家的动画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:录屏真是挺麻烦的 不知道有什么简单好用工具推荐)
这里写图片描述

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