Android群英转读书笔记第七章(Android动画机制与使用技巧)

动画的分类

动画分为视图动画(View)和属性动画(Property),而视图动画又分为Tween动画和Frame动画,属性动画又分为ValueAnimator和ObjectAnimator.

属性动画简介

从Android3.0开始出现,真实改变View的属性,可以响应事件

使用ObjectAnimator时,对象的属性必须有get和set方法,因为内部会通过反射来调用属性的set方法,如果一个属性没有get和set方法,可以通过下面两种方式来解决。
1.自定义一个属性类或者包装类
2.使用ValueAnimator

public class WrapperView {
    private View mTargetView;

    public WrapperView(View targetView){
        mTargetView = targetView;
    }
    public int getWidth(){
        return mTargetView.getLayoutParams().width;
    }
    public void setWidth(int width){
        mTargetView.getLayoutParams().width = width;
        mTargetView.requestLayout();
    }
}
public class MainActivity extends AppCompatActivity {

    private WrapperView wrapperView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button) findViewById(R.id.button);
        wrapperView = new WrapperView(btn);
    }
    public void click(View view){
        ObjectAnimator.ofInt(wrapperView,"width",0,500).setDuration(5000).start();
    }
}

这里写图片描述

在属性动画中,使用PropertyValueHolder可以使多个动画共同作用,用法类似于AnimationSet的使用。

ValueAnimator
本身不提供任何动画效果,更像一个数值发生器,用来产生一定规律的数字,从而让调用者控制动画的实现过程。用法如下
这里写图片描述

    //创建对象
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1);
        //设置要添加动画的view
        valueAnimator.setTarget(btn);
        valueAnimator.setDuration(4000);
        //启动动画
        valueAnimator.start();
        //添加监听
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //不断获取动画过程中的值
                float animatedValue = (float) animation.getAnimatedValue();
                btn.setAlpha(animatedValue);
            }
        });

AnimatorSet也可以对一个属性进行多个动画,还能控制顺序,比前面的PropertyValueHolder更强大。

View的animate方法
在API16之后,提供了animate方法直接驱动属性动画

这里写图片描述

    btn.animate().alpha(0).y(200).setDuration(2000)
              .withStartAction(new Runnable() {
                  @Override
                  public void run() {
                      Toast.makeText(MainActivity.this, "开始", Toast.LENGTH_SHORT).show();
                  }
              }).withEndAction(new Runnable() {
          @Override
          public void run() {
              Toast.makeText(MainActivity.this, "结束", Toast.LENGTH_SHORT).show();
          }
      });
    }

布局动画
布局动画是指作用在ViewGroup上,给ViewGroup添加View时增加一个动画效果。
这里写图片描述

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ll = (LinearLayout) findViewById(R.id.ll);
        TranslateAnimation animation = new TranslateAnimation(720,0,0,0);
        animation.setDuration(2000);
        LayoutAnimationController controller = new LayoutAnimationController(animation,0.5f);
        controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
        ll.setLayoutAnimation(controller);
        addView();
    }
    public void addView(){
        for (int i = 0; i < 10; i++) {
            TextView textView  = new TextView(this);
            textView.setText("文字"+i);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
                    (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            ll.addView(textView,params);
        }
    }

自定义动画
步骤:
1.重写initialize方法做初始化动作
2.重写applyTransformation方法

这里写图片描述

public class RotateAnim extends Animation {
    private int mCenterWidth;
    private int mCenterHeight;
    private Camera camera = new Camera();
    private float mRotateY = 0.0f;
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        setDuration(2000);
        setFillAfter(true);
        setInterpolator(new BounceInterpolator());
        mCenterWidth = width/2;
        mCenterHeight = height/2;
    }
    public void setRotateY(float rotateY){
        mRotateY = rotateY;
    }
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        Matrix matrix = t.getMatrix();
        camera.save();
        camera.rotateY(mRotateY*interpolatedTime);
        camera.getMatrix(matrix);
        camera.restore();
        //设置旋转中心,
        matrix.preTranslate(mCenterWidth/2,mCenterHeight);
        matrix.postTranslate(-mCenterWidth/2,-mCenterHeight);
    }
}

Android 5.X SVG 矢量动画机制
SVG是可伸缩矢量图形,使用XML格式定义图形,图像在放大或者改变尺寸的情况下图像质量不会有损失。

Android中使用SVG需要使用下面两个API

VectorDrawable:创建基于XML的SVG图形
AnimatedVerctorDrawable:实现动画效果,比喻为一个胶水,连接静态的VectorDrawable和动态的objectAnimator

动画特效

这里写图片描述

public class MainActivity extends AppCompatActivity {

    private LinearLayout hiddenView;
    private LinearLayout ll;
    private boolean flag = false;
    private float density;
    private int hiddenViewHeight;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        density = getResources().getDisplayMetrics().density;
        hiddenViewHeight = (int) (density*40+0.5f);
        ll = (LinearLayout) findViewById(R.id.ll);
        hiddenView = (LinearLayout) findViewById(R.id.hiddenView);
        ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(hiddenView.getVisibility() == View.GONE){
                    hiddenView.setVisibility(View.VISIBLE);
                    ValueAnimator animator = createAnimation(hiddenView, 0, hiddenViewHeight);
                    animator.start();
                }else{
                    int oriHeight = hiddenView.getHeight();
                    ValueAnimator animator = createAnimation(hiddenView, oriHeight, 0);
                    animator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            hiddenView.setVisibility(View.GONE);
                        }
                    });
                    animator.start();
                }
            }
        });
    }

    public ValueAnimator createAnimation(final View view, int start, int end){
        ValueAnimator animator = ValueAnimator.ofInt(start,end);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
                params.height = (int) animation.getAnimatedValue();
                view.setLayoutParams(params);
            }
        });
        flag = true;
        return animator;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值