Android 自定义动画view(小变大,旋转,色值)

也不知道到看了多少的动画总结了,但是用到的时候太少,过段时间就会忘记了。

既然如此,我选择直接去动手学习,步步进阶。

效果:

上代码之前我们分析一下才会加深自己的印象:

  • 需要画一个矩形 和 一个圆形
  • 需要计算位置,距离,大小
  • 需要缩放,旋转,颜色渐变动画

代码:

package com.example.administrator.firsttest.animView;

import android.animation.AnimatorSet;
import android.animation.Keyframe;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;

/**
 * Created by Administrator on 2018/8/7.
 */

public class MyView extends View {

    Paint mPaint;
    int lineWidth = 10;
    int ratio = 50;
    int mColor = Color.BLUE;
    float rotate;

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(lineWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 由于动画中有更改颜色,所以这里每次onDraw都要重新设置下画笔颜色
        mPaint.setColor(mColor);
        //旋转动画,直接旋转画布即可
        canvas.rotate(rotate, getWidth() / 2, getHeight() / 2);
        // 画正方形,ratio为可边长的一半
        canvas.drawRect(getWidth() / 2 - ratio / 2, getHeight() / 2 - ratio / 2, getWidth() / 2 + ratio / 2, getHeight() / 2 + ratio / 2, mPaint);
        // 画圆形,ratio为半径
        canvas.drawCircle(getWidth() / 2, getHeight() / 2 - 2 * ratio, ratio, mPaint);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void start(){

        // 旋转动画,通过改变rotate值实现
        ValueAnimator rotateAni = ValueAnimator.ofFloat(0, 360);
        //无限重复
        rotateAni.setRepeatCount(Animation.INFINITE);
        // 设置监听,赋值给rotate
        rotateAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                rotate = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        //放大动画,通过改变ratio实现
        ValueAnimator rotateAnimator = ValueAnimator.ofInt(50, 100);
        rotateAnimator.setInterpolator(new LinearInterpolator());
        rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ratio = (int) animation.getAnimatedValue();
            }
        });
        rotateAnimator.setRepeatCount(-1);
        // 设置重复的模式为原样恢复,即放大后再按原路缩小,这样才不会出现跳动
        rotateAnimator.setRepeatMode(ValueAnimator.REVERSE);

        //颜色变化动画
        ValueAnimator colorAni = ValueAnimator.ofArgb(Color.BLUE, Color.GREEN);
        colorAni.setInterpolator(new LinearInterpolator());
        colorAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mColor = (int) animation.getAnimatedValue();
            }
        });
        colorAni.setRepeatCount(-1);
        // 设置重复的模式为原样恢复,即放大后再按原路缩小,这样才不会出现跳动
        colorAni.setRepeatMode(ValueAnimator.REVERSE);

        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        set.play(rotateAnimator).with(colorAni).with(rotateAni);
        set.start();


        Keyframe keyframe = Keyframe.ofFloat(0f, 0);

    }

}
//我在例子中用的都是ValueAnimator,其实还有其它相关类,比如ObjectAnimator改变透明度:
//ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
//animator.setDuration(5000);
//animator.start();
//另外还有ViewPropertyAnimator,用起来更方便,不过只有有限的方法,比如让view在x轴y轴都平衡500:
//textview.animate().x(500).y(500).setDuration(5000)
//.setInterpolator(new BounceInterpolator());
//最后最后,再说一个PropertyValuesHolder,它保存了动画过程中所需要操作的属性和对应的值,
//通常和Keyframe一起使用。像实现一个View抖动动画时,你用上面的需要写很多重复的动画进行串联起来,
//但用Keyframe就可以很好的一次性把动画描述清楚。Keyframe其实就是动画的关键帧。举个抖动的实现例子:
//Keyframe frame0 = Keyframe.ofFloat(0f, 0);
//    Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
//    Keyframe frame2 = Keyframe.ofFloat(1, 0);
//    PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2);
//    Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage,frameHolder);
//animator.setDuration(1000);
//        animator.start();

xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.firsttest.activity.AnimActivity">

    <com.example.administrator.firsttest.animView.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/myView"
        />

</LinearLayout>

activity:

package com.example.administrator.firsttest.activity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.example.administrator.firsttest.R;
import com.example.administrator.firsttest.animView.MyView;

public class AnimActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_anim);

        ((MyView) findViewById(R.id.myView)).start();
    }
}

代码中已经有注释了,但是我们还是要去总结一下

动画中的三种动画:

1.补间动画

通过场景里的对象不断做图像变换(平移,缩放,旋转,透明度)从而产生动画效果,是一种渐近式动画,并支持自定义。

2.属性动画

属相动画通过动态地改变对象的属性从而达到动画效果。

3.帧动画

帧动画其实也属于View动画。通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画效果,但图片过多过大会导致OOM

动画中的插值器

@android:anim/accelerate_interpolator: 越来越快

@android:anim/decelerate_interpolator:越来越慢

@android:anim/accelerate_decelerate_interpolator:先快后慢

@android:anim/anticipate_interpolator: 先后退一小步然后向前加速

@android:anim/overshoot_interpolator:快速到达终点超出一小步然后回到终点

@android:anim/anticipate_overshoot_interpolator:到达终点超出一小步然后回到终点

@android:anim/bounce_interpolator:到达终点产生弹球效果,弹几下回到终点

@android:anim/linear_interpolator:均匀速度。

 

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是Android实现图片放大缩小动画的方法: 1.在XML布局文件中添加ImageView组件,并设置其初始大小和位置。 2.在Java代码中,使用ObjectAnimator类创建一个动画对象,并设置动画的目标对象、属性和动画效果。 3.在动画结束后,需要将ImageView的大小和位置还原为初始状态。 具体实现步骤如下: ```xml <!-- 在XML布局文件中添加ImageView组件 --> <ImageView android:id="@+id/imageView" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/image" android:scaleType="centerCrop" android:layout_centerInParent="true"/> ``` ```java // 在Java代码中实现动画效果 ImageView imageView = findViewById(R.id.imageView); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 创建动画对象 ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 1.5f); ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 1.5f); AnimatorSet set = new AnimatorSet(); set.play(animatorX).with(animatorY); set.setDuration(500); set.start(); // 动画结束后还原ImageView的大小和位置 set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageView, "scaleX", 1.5f, 1f); ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageView, "scaleY", 1.5f, 1f); AnimatorSet set = new AnimatorSet(); set.play(animatorX).with(animatorY); set.setDuration(500); set.start(); } }); } }); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值