• 实现Path2.0中绚丽的的旋转菜单


    上图先:

             那么下面开始吧~

             首先,将整个菜单动画分解开来。

    1.       一级菜单按钮的旋转动画2个,十字和叉叉状态的转换。

    2.       二级菜单按钮的平移动画2个,弹簧效果的inout

    3.       二级菜单按钮的点击效果,放大消失,其他未点击按钮缩小消失。

    4.       一级菜单按钮的恢复效果,放大出现

    好的 逐一去实现:

    首先是一级菜单按钮的旋转动画,这2个动画可以直接在xml中定义,然后load到代码中来,具体代码如下:

    rotate_story_add_button_in.xml 

    <?xml version="1.0" encoding="UTF-8"?>
    <rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator
    ="@android:anim/linear_interpolator"
    android:duration
    ="150"
    android:fromDegrees
    ="0.0"
    android:toDegrees
    ="-225.0"
    android:pivotX
    ="50.0%"
    android:pivotY
    ="50.0%"
    android:fillAfter
    ="true"
    android:fillEnabled
    ="true"
    />

    rotate_story_add_button_out.xml 

    <?xml version="1.0" encoding="UTF-8"?>
    <rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator
    ="@android:anim/linear_interpolator"
    android:duration
    ="150"
    android:fromDegrees
    ="-225.0"
    android:toDegrees
    ="0.0"
    android:pivotX
    ="50.0%"
    android:pivotY
    ="50.0%"
    android:fillAfter
    ="true"
    android:fillEnabled
    ="true"
    />

     2段没什么好说的,定义好角度即可。

    接下来是需要我们在代码中定义的动画部分,这几个动画的部分需要定义一个基类,作为统一的调用接口,这个基类被称作InOutAnimation,继承自AnimationSet,这个基类的主要工作是为view提供inout两种不同的状态时的动画效果。其子类需要实现2个方法: 

    protected abstract void addInAnimation(View aview[]);
    protected abstract void addOutAnimation(View aview[]);

     从而进行view的入场和离场动画。

    下面是InOutAnimation的代码部分: 

    public abstract class InOutAnimation extends AnimationSet {

    public Direction direction;

    public enum Direction {
    IN, OUT;
    }

    public InOutAnimation(Direction direction, long l, View[] aview) {
    super(true);
    this.direction = direction;
    switch (this.direction) {
    case IN:
    addInAnimation(aview);
    break;
    case OUT:
    addOutAnimation(aview);

    break;
    }
    setDuration(l);
    }

    protected abstract void addInAnimation(View aview[]);

    protected abstract void addOutAnimation(View aview[]);

    }

    接下来就是重头戏啦,二级菜单按钮的平移动画。

    这部分动画看起来可能会比较复杂和神秘,其实不然,当把整个动画过程分解开来的时候,都是最最简单的平移而已,我们要做的只是定义一下平移的起点和终点、开始动画的顺序以及插值(Interpolator),让整个过程看起来很炫。

    先说动画的起点和终点吧,起点很简单,就是整个view的左下角,即0,0点,为了效果漂亮一些,我们稍微的将左下角位置定义的有一些偏移,经验上的值是16-13,这个点的位置看你心情而定咯 终点就是你想让他在的点上就好了,终点我们将定义到layout中去,为这个2级菜单指定一个margin的值就好。

    还是上代码比较直观:

    动画如下: 

    收缩部分:TranslateAnimation(xOffset + -mlp.leftMargin, 0F,yOffset + mlp.bottomMargin, 0F)
    扩张部分:TranslateAnimation(0F, xOffset + -mlp.leftMargin, 0F,yOffset + mlp.bottomMargin)

    位置定义部分:

    例如:

    android:layout_marginBottom="142dp"  android:layout_marginLeft="10.667dp"

    这个位置大家可以直观的在布局文件中看到,详细的布局文件也将在下面展示。

    以上是单独的每一个二级按钮的动画,而组合的动画就是指定了一下开始的时间差以及插值:

    这个就是奥妙所在了,OvershootInterpolator AnticipateInterpolator 2个插值器提供了弹力效果。

    整段的代码如下:

    ComposerButtonAnimation.java 

    public class ComposerButtonAnimation extends InOutAnimation {

    public static final int DURATION = 500;
    private static final int xOffset = 16;
    private static final int yOffset = -13;

    public ComposerButtonAnimation(Direction direction, long l, View view) {
    super(direction, l, new View[] { view });
    }

    public static void startAnimations(ViewGroup viewgroup,
    InOutAnimation.Direction direction) {
    switch (direction) {
    case IN:
    startAnimationsIn(viewgroup);
    break;
    case OUT:
    startAnimationsOut(viewgroup);
    break;
    }
    }

    private static void startAnimationsIn(ViewGroup viewgroup) {
    for (int i = 0; i < viewgroup.getChildCount(); i++) {
    if (viewgroup.getChildAt(i) instanceof InOutImageButton) {
    InOutImageButton inoutimagebutton = (InOutImageButton) viewgroup
    .getChildAt(i);
    ComposerButtonAnimation animation = new ComposerButtonAnimation(
    InOutAnimation.Direction.IN, DURATION, inoutimagebutton);
    animation.setStartOffset((i * 100)
    / (-1 + viewgroup.getChildCount()));
    animation.setInterpolator(new OvershootInterpolator(2F));
    inoutimagebutton.startAnimation(animation);
    }
    }
    }

    private static void startAnimationsOut(ViewGroup viewgroup) {
    for (int i = 0; i < viewgroup.getChildCount(); i++) {
    if (viewgroup.getChildAt(i) instanceof InOutImageButton) {
    InOutImageButton inoutimagebutton = (InOutImageButton) viewgroup
    .getChildAt(i);
    ComposerButtonAnimation animation = new ComposerButtonAnimation(
    InOutAnimation.Direction.OUT, DURATION,
    inoutimagebutton);
    animation.setStartOffset((100 * ((-1 + viewgroup
    .getChildCount()) - i))
    / (-1 + viewgroup.getChildCount()));
    animation.setInterpolator(new AnticipateInterpolator(2F));
    inoutimagebutton.startAnimation(animation);
    }
    }
    }

    @Override
    protected void addInAnimation(View[] aview) {
    MarginLayoutParams mlp = (MarginLayoutParams) aview[0]
    .getLayoutParams();
    addAnimation(new TranslateAnimation(xOffset + -mlp.leftMargin, 0F,
    yOffset + mlp.bottomMargin, 0F));
    }

    @Override
    protected void addOutAnimation(View[] aview) {
    MarginLayoutParams mlp = (MarginLayoutParams) aview[0]
    .getLayoutParams();
    addAnimation(new TranslateAnimation(0F, xOffset + -mlp.leftMargin, 0F,
    yOffset + mlp.bottomMargin));
    }
    }

    剩下的增大出现、增大消失及缩小消失都是scalealpha的组合动画

    例如增大出现为: 

    addAnimation(new ScaleAnimation(0F, 1F, 0F, 1F, 1, 0.5F, 1, 0.5F));
    addAnimation(new AlphaAnimation(0F, 1F));

     整段的代码如下: 

    public class ComposerButtonGrowAnimationIn extends InOutAnimation {

    public ComposerButtonGrowAnimationIn(int i) {
    super(InOutAnimation.Direction.IN, i, new View[0]);
    }

    @Override
    protected void addInAnimation(View[] aview) {
    addAnimation(new ScaleAnimation(0F, 1F, 0F, 1F, 1, 0.5F, 1, 0.5F));
    addAnimation(new AlphaAnimation(0F, 1F));

    }

    @Override
    protected void addOutAnimation(View[] aview) {}

    }

    public class ComposerButtonGrowAnimationOut extends InOutAnimation {

    public ComposerButtonGrowAnimationOut(int i) {
    super(InOutAnimation.Direction.OUT, i, new View[0]);
    }

    @Override
    protected void addInAnimation(View[] aview) {}

    @Override
    protected void addOutAnimation(View[] aview) {
    addAnimation(new ScaleAnimation(1F, 5F, 1F, 5F, 1, 0.5F, 1, 0.5F));
    addAnimation(new AlphaAnimation(1F, 0F));
    }

    } public class ComposerButtonShrinkAnimationOut extends InOutAnimation {

    public ComposerButtonShrinkAnimationOut(int i) {
    super(InOutAnimation.Direction.OUT, i, new View[0]);
    }

    @Override
    protected void addInAnimation(View[] aview) {

    }

    @Override
    protected void addOutAnimation(View[] aview) {
    addAnimation(new ScaleAnimation(1F, 0F, 1F, 0F, 1, 0.5F, 1, 0.5F));
    addAnimation(new AlphaAnimation(1F, 0F));
    }

    }

    接下来我们需要为这些控件做一下扩展,以便其可以再动画完成后显示或消失。

    很简单 

    public class InOutImageButton extends ImageButton {

    private Animation animation;

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

    public InOutImageButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    }

    public InOutImageButton(Context context) {
    super(context);
    }

    @Override
    protected void onAnimationEnd() {
    super.onAnimationEnd();
    if ((this.animation instanceof InOutAnimation)) {
    setVisibility(((InOutAnimation) this.animation).direction != InOutAnimation.Direction.OUT ? View.VISIBLE
    : View.GONE);
    }
    }

    @Override
    protected void onAnimationStart() {
    super.onAnimationStart();
    if ((this.animation instanceof InOutAnimation))
    setVisibility(View.VISIBLE);
    }

    @Override
    public void startAnimation(Animation animation) {
    super.startAnimation(animation);
    this.animation = animation;
    getRootView().postInvalidate();
    }
    }

    那么到这里基本上就已经搞定了所有的事情了,剩下点没做的事就是把这些动画效果设置给对应的控件了.

    源码:https://files.cnblogs.com/shanzei/PureComposerDemo.rar

    转自:http://www.cnblogs.com/mudoot/archive/2012/01/19/path_composer_menu.html

  • 相关阅读:
    横竖屏切换
    org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: unknown encoding
    @Value() 使用方法
    调用第三方超时处理
    spring 配置注解定时器quartz01
    tomcat:PermGen space
    06-图3 六度空间 (30分)
    06-图2 Saving James Bond
    06-图1 列出连通集 (25分)
    05-树9 Huffman Codes (30分)
  • 原文地址:https://www.cnblogs.com/shanzei/p/2415698.html
Copyright © 2020-2023  润新知