Android动画学习记录二(属性动画、估值期和插值器)

Android动画学习记录二(属性动画、估值期和插值器)

  • Android动画学习记录二(属性动画、估值期和插值器)
  • 一、补间动画缺陷
  • 二、属性动画
  • 三、三种常见的属性动画类
    • ValueAnimator
      • ValueAnimator.ofInt()
      • ValueAnimator.oFloat()
      • ValueAnimator.ofObject()
    • ObjectAnimator
      • ObjectAnimator.ofFloat(Object object, String property, float ....values);
    • AnimatorSet
  • 四、TypeEvaluator(估值器)和Interpolator(插值器)
    • TypeEvaluator(估值器)
    • Interpolator(插值器)
    • 小结
  • 五、属性动画的监听器
  • 六、XML编写动画
    • 参考资料

自API 11 Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation),它弥补了之前补间动画的一些缺陷,几乎可以完全替代掉补间动画了。关于补间动画可以看这篇,https://blog.csdn.net/qq_53749266/article/details/123571771?spm=1001.2014.3001.5502

如果只需要对View进行移动、缩放、旋转和淡入淡出操作,那么补间动画确实已经足够了。但是很显然,这些功能是不足以覆盖所有的场景的,那么下面我们就来看看补间动画所不能胜任的场景。

一、补间动画缺陷

补间动画:

  1. 补间动画是只能够作用在View上的使用补间我们其它任何继承自View的组件进行动画操作,但是如果我们想要对一个非View的对象进行动画操作,补间动画就帮不上忙了。
  2. 补间动画只能为 View 添加动画效果,但不能监听 View 相关属性的变化过程。
  3. 补间动画提供的动画能力较为单一,目前只支持缩放动画****(Scale)、平移动画(Translate)、旋转动画(Rotate)、透明度动画(Alpha)****以及这些动画的集合动画,扩展性很差。
  4. 补间动画改变的是 View 的绘制效果,View 的真正位置相关属性并不会改变,这也就造成了点击事件的触发区域是动画前的位置而不是动画后的位置的原因。

二、属性动画

属性动画:

  1. 属性动画作用对象不局限在 View 上,而是任何提供了 Getter 和 Setter 方法的对象的属性上。
  2. 属性动画通过动态改变 View 相关属性的方式来改变 View 的显示效果。移动一个按钮,那么这个按钮就是真正的移动了,而不再是仅仅在另外一个位置绘制了而已。
  3. 属性动画对于 propertyName 需要自己去挖掘,或者自己通过 Wrapper 的方式去自定义 propertyName

那属性动画的使用场景有哪些呢?

  • 基本上补间动画作用在 View 上的动画效果,属性动画都可以实现;
  • 在自定义 View 时,需要实现一些复杂的动画效果,或对 View 的一些特殊属性值进行动画变更时,补间动画无法实现时;
  • 另外,属性动画你也可以用在非动画场景,比如,你在自定义 View 需要一个有一定规律(根据特定差值器变化)且可监听的数值变化器,这个时候借助属性动画是再合适不过了。

三、三种常见的属性动画类

ValueAnimator

ValueAnimator本质通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果,是整个属性动画机制当中最核心的一个类,初始值和结束值之间的动画过渡就是由ValueAnimator类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。可以将ValueAnimator看着一个值变化器,即在给定的时间内将一个目标值从给定的开始值变化到给定的结束值。在使用ValueAnimator时通常需要添加一个动画更新的监听器,在监听器中能够获取到执行过程中的每一个动画值。

ValueAnimator.ofInt()

将初始值 以整型数值的形式 过渡到结束值,即估值器是整型估值器 - IntEvaluator

ofInt()作用:

  1. 创建动画实例
  2. 将传入的多个Int参数进行平滑过渡:此处传入0和3,表示将值从0平滑过渡到3
    如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到C,以此类推
    ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如何从初始值 过渡到 结束值
    java方式
// 步骤1:设置动画属性的初始值 & 结束值
ValueAnimator anim = ValueAnimator.ofInt(0, 3);
/ 步骤2:设置动画的播放各种属性
// 设置动画运行的时长
anim.setDuration(500); // 设置动画延迟播放时间
anim.setStartDelay(500); // 设置动画重复播放次数 = 重放次数+1
// 动画播放次数 = infinite时,动画无限重复
anim.setRepeatCount(0);// 设置重复播放动画模式
anim.setRepeatMode(ValueAnimator.RESTART);
// ValueAnimator.RESTART(默认):正序重放
// ValueAnimator.REVERSE:倒序回放// 步骤3:将改变的值手动赋值给对象的属性值:通过动画的更新监听器
// 设置值的更新监听器,即:值每次改变、变化一次,该方法就会被调用一次
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {// 获得改变后的值int currentValue = (Integer) animation.getAnimatedValue();// 将改变后的值赋给对象的属性值,下面会详细说明View.setproperty(currentValue);// 刷新视图,即重新绘制,从而实现动画效果View.requestLayout();}});// 步骤4:启动动画
anim.start();

xml方式

res/animator/set_animation.xml
<animator xmlns:android="http://schemas.android.com/apk/res/android"  android:valueFrom="0"   // 初始值android:valueTo="3"  // 结束值android:valueType="intType" // 变化值类型 :floatType & intTypeandroid:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果android:startOffset ="1000" // 动画延迟开始时间(ms)android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为trueandroid:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为falseandroid:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为trueandroid:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restartandroid:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度
/> // 载入XML动画
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation);
// 设置动画对象
animator.setTarget(view);
// 启动动画
animator.start();
  • android:propertyName——表示属性动画的作用对象的属性的名称;
  • android:duration——表示动画的时长;
  • android:valueFrom——表示属性的起始值;
  • android:valueTo——表示属性的结束值;
  • android:startOffset——表示动画的延迟时间,当动画开始后,需要延迟多少毫秒才会真正播放此动画;
  • android:fillBefore——动画播放完后,视图是否会停留在动画开始的状态,默认为true
  • android:fillAfter——动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
  • android:repeatMode——选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart
  • android:fillEnabled——是否应用fillBefore值,对fillAfter值无影响,默认为true
  • android:repeatCount——重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
  • android:valueType——表示android:propertyName所指定的属性的类型,有“intType”和“floatType”两个可选项,分别表示属性的类型为整型和浮点型。另外,如果android:propertyName所指定的属性表示的是颜色,那么不需要指定android:valueType,系统会自动对颜色类型的属性做处理。

ValueAnimator.oFloat()

将初始值 以浮点型数值的形式 过渡到结束值,只展示与ValueAnimator.ofInt()的区别之处

/** 设置方式1:xml*/
<animator xmlns:android="http://schemas.android.com/apk/res/android"  android:valueFrom="0"  android:valueTo="3"  android:valueType="floatType" // 区别:设置为浮点型类型... // 其余属性设置跟ValueAnimator.ofInt类似/>  /** 设置方式2:Java*/
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
//添加监听器
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {//这个方法可以拿到当前的值float currentValue = (float) animation.getAnimatedValue();Log.d("TAG", "cuurent value is " + currentValue);}});
anim.start();

ValueAnimator.ofInt()与ValueAnimator.oFloat()仅仅只是在估值器上的区别:(即如何从初始值 过渡 到结束值)

ValueAnimator.oFloat()采用默认的浮点型估值器 (FloatEvaluator)
ValueAnimator.ofInt()采用默认的整型估值器(IntEvaluator)
在使用上完全没有区别

ValueAnimator.ofObject()

将初始值 以对象的形式 过渡到结束值,即通过操作 对象 实现动画效果。

参数说明
参数1:自定义的估值器对象(TypeEvaluator)
参数2:初始动画的对象
参数3:结束动画的对象

// 1. 创建初始动画时的对象  & 结束动画时的对象
myObject object1 = new myObject();
myObject object2 = new myObject();  // 2. 创建动画对象
ValueAnimator anim = ValueAnimator.ofObject(new myObjectEvaluator(), object1, object2);  // 3. 设置参数
anim.setDuration(5000);  // 4. 启动动画
anim.start();

ValueAnimator的作用:只是对值进行了一个平滑的动画过渡

ObjectAnimator

直接对对象的属性值进行改变操作,从而实现动画效果。ObjectAnimator继承自ValueAnimator,它是可以直接对任意对象的任意属性进行动画操作的,比如说Viewtranslate(平移),scale(缩放),rotate(旋转),alpha(渐变)属性。

ObjectAnimator.ofFloat(Object object, String property, float …values);

作用:

  1. 创建动画实例
  2. 参数设置:
    Object object:需要操作的对象
    String property:需要操作的对象的属性
    float …values:动画初始值 & 结束值(不固定长度)
    若是两个参数a,b,则动画效果则是从属性的a值到b值,若是三个参数a,b,c,则则动画效果则是从属性的a值到b值再到c值,以此类推。

至于如何从初始值过渡到结束值,同样是由估值器决定,此处ObjectAnimator.ofFloat()是有系统内置的浮点型估值器FloatEvaluator

Java代码
// 步骤1:创建ObjectAnimator对象
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "rotation", 0f, 360f);
// 其实Button对象中并没有rotation这个属性值
// ObjectAnimator并不是直接对我们传入的属性名进行操作
// 而是根据传入的属性值"rotation" 去寻找对象对应属性名对应的get和set方法,从而通过set()、get()对属性进行赋值// 因为Button对象中有rotation属性所对应的get & set方法
// 所以传入的rotation属性是有效的
// 所以才能对rotation这个属性进行操作赋值// 步骤2:设置动画属性
// 设置动画运行的时长
public void setRotation(float value);
public float getRotation();  // 实际上,这两个方法是由View对象提供的,所以任何继承自View的对象都具备这个属性
// 设置动画延迟播放时间
anim.setStartDelay(500);// 设置动画重复播放次数 = 重放次数+1
// 动画播放次数 = infinite时,动画无限重复
anim.setRepeatCount(0);// 设置重复播放动画模式
anim.setRepeatMode(ValueAnimator.RESTART);
// ValueAnimator.RESTART(默认):正序重放
// ValueAnimator.REVERSE:倒序回放// 步骤3:启动动画
animator.start();

xml代码:

//创建 res/animator/set_animation.xml设置动画参数
// ObjectAnimator 采用<animator>  标签
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  android:valueFrom="1"   // 初始值android:valueTo="0"  // 结束值android:valueType="floatType"  // 变化值类型 :floatType & intTypeandroid:propertyName="alpha" // 对象变化的属性名称
/> // 步骤3:启动动画
// 1. 载入XML动画
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.view_animation);
// 2. 设置动画对象
animator.setTarget(view);
// 3. 启动动画
animator.start();

大部分方法与ValueAnimator类似。

可以理解为:ObjectAnimator更加智能、自动化程度更高

  • ValueAnimator 类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;
  • ObjectAnimator 类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接 对对象属性进行操作;

AnimatorSet

借助AnimatorSet这个类我们可以实现组合动画功能,实现组合大致有如下两种方法:

play()方法
如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();

方法名 说明

  • after(Animator anim) 将现有动画插入到传入的动画之后执行
  • after(long delay) 将现有动画延迟指定毫秒后执行
  • before(Animator anim) 将现有动画插入到传入的动画之前执行
  • with(Animator anim) 将现有动画和传入的动画同时执行

playTogether方法
这个方法只能让所有的动画一起执行,相等于上面的with
使用:

AnimatorSet set = new AnimatorSet();
set.playTogether(ObjectAnimator.ofFloat(textView,"rotationX",0,360,0),     //在水平方向进行旋转ObjectAnimator.ofFloat(textView,"rotationY",0,180,0),     //在垂直方向进行旋转ObjectAnimator.ofFloat(textView,"rotation",0,-90,0),      //旋转ObjectAnimator.ofFloat(textView,"translationX",0,90,0),   //在水平方向平移ObjectAnimator.ofFloat(textView,"translationY",0,90,0),   //在垂直方向平移ObjectAnimator.ofFloat(textView,"scaleX",1,1.5f,1),       //在水平方向上进行缩放ObjectAnimator.ofFloat(textView,"scaleY",0,0.5f,1),       //在垂直方向上进行缩放ObjectAnimator.ofFloat(textView,"alpha",1,0.25f,1)      //透明度
);
set.setDuration(5000).start();

四、TypeEvaluator(估值器)和Interpolator(插值器)

TypeEvaluator(估值器)

在插值器(Interpolator)决定 值 的变化规律(匀速、加速blabla),即决定是变化趋势后;接下来的具体变化数值则交给而估值器Interpolator),估值器(Interpolator)的作用是告诉动画系统如何从初始值过度到结束值,根据当前属性改变的百分比来计算改变后的属性值。ValueAnimator.ofInt() & ValueAnimator.ofFloat()都具备系统内置的估值器,即FloatEvaluator & IntEvaluator,即系统已经默认实现了 如何从初始值 过渡到 结束值 的逻辑。

系统预设的有IntEvaluator(针对整型属性),FloatEvaluator(针对浮点型属性),和ArgbEvaluator(针对Color属性)。

public class FloatEvaluator implements TypeEvaluator {public Object evaluate(float fraction, Object startValue, Object endValue) {float startFloat = ((Number) startValue).floatValue();return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);}
}

第一个参数fraction非常重要,这个参数用于表示动画的完成度的,我们应该根据它来计算当前动画的值应该是多少,第二第三个参数分别表示动画的初始值结束值。那么上述代码的逻辑就比较清晰了,用结束值减去初始值,然后乘以fraction这个系数,再加上初始值,就得到了当前动画的值

但对于第三个方法ValueAnimator.ofObject(),从上面的工作原理可以看出并没有系统默认实现,因为对对象的动画操作复杂 & 多样,系统无法知道如何从初始对象过度到结束对象
因此,对于ValueAnimator.ofObject(),我们需自定义估值器(TypeEvaluator)来告知系统如何进行从 初始对象 过渡到 结束对象的逻辑。

有一个非常简单的Point类,只有x和y两个变量用于记录坐标的位置,并提供了构造方法来设置坐标,以及get方法来获取坐标。

public class PointEvaluator implements TypeEvaluator{@Overridepublic Object evaluate(float fraction, Object startValue, Object endValue) {Point startPoint = (Point) startValue;Point endPoint = (Point) endValue;float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());Point point = new Point(x, y);return point;}
}

evaluate()中先是将startValueendValue强转成Point对象,然后同样根据fraction来计算当前动画的x和y的值,最后组装到一个新的Point对象当中并返回。ofObject()方法要求多传入一个TypeEvaluator参数,这里我们只需要传入刚才定义好的PointEvaluator的实例就可以了。

//将Point1通过动画平滑过度到Point2
Point point1 = new Point(0, 0);
Point point2 = new Point(300, 300);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), point1, point2);
anim.setDuration(5000);
anim.start();public class MyAnimView extends View {public static final float RADIUS = 50f;private Point currentPoint;private Paint mPaint;public MyAnimView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.BLUE);}@Overrideprotected void onDraw(Canvas canvas) {if (currentPoint == null) {currentPoint = new Point(RADIUS, RADIUS);drawCircle(canvas);startAnimation();} else {drawCircle(canvas);}}//在currentPoint的坐标位置画出一个半径为50的圆private void drawCircle(Canvas canvas) {float x = currentPoint.getX();float y = currentPoint.getY();canvas.drawCircle(x, y, RADIUS, mPaint);}private void startAnimation() {Point startPoint = new Point(RADIUS, RADIUS);//View的左上角Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);//右下角ValueAnimator anim = ValueAnimator.ofObject(new **PointEvaluator**(), startPoint, endPoint);anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Override
//当Point值有改变的时候都会回调onAnimationUpdate()方法public void onAnimationUpdate(ValueAnimator animation) {//currentPoint对象进行了重新赋值,并调用了invalidate()方法,onDraw()方法就会重新调用,
//并且由于currentPoint对象的坐标已经改变了,绘制的位置也会改变,于是一个平移的动画效果也就实现了。currentPoint = (Point) animation.getAnimatedValue();//请求重绘View树,即draw()过程,假如视图发生大小没有变化就不会调用layout()过程,
//并且只绘制那些“需要重绘的”invalidate();}});anim.setDuration(5000);anim.start();}}

Interpolator(插值器)

主要作用是可以根据时间流逝的百分比来计算当前属性值的百分比,控制动画的变化速率。比如去实现一种非线性运动的动画效果
非线性运动:动画改变的速率不是一成不变的,如加速 & 减速运动都属于非线性运动

插值器在动画的使用有两种方式:在XML / Java代码中设置:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/overshoot_interpolator"// 通过资源ID设置插值器android:duration="3000"android:fromXScale="0.0"android:fromYScale="0.0"android:pivotX="50%"android:pivotY="50%"android:toXScale="2"android:toYScale="2" />// 步骤1:创建 需要设置动画的 视图View
Button mButton = (Button) findViewById(R.id.Button);// 步骤2:创建透明度动画的对象 & 设置动画效果
Animation alphaAnimation = new AlphaAnimation(1,0);
alphaAnimation.setDuration(3000);// 步骤3:创建对应的插值器类对象
Interpolator overshootInterpolator = new OvershootInterpolator();// 步骤4:给动画设置插值器
alphaAnimation.setInterpolator(overshootInterpolator);// 步骤5:播放动画
mButton.startAnimation(alphaAnimation);
作用 资源ID 对应的Java类
动画加速进行 @android:anim/accelerate_interpolator AccelerateInterpolator
快速完成动画,超出再回到结束样式 @android:anim/overshoot_interpolator OvershootInterpolator
先加速再减速 @android:anim/accelerate_decelerate_interpolator AccelerateDecelerateInterpolator
先退后再加速前进 @android:anim/anticipate_interpolator AnticipateInterpolator
先退后再加速前进,超出终点后再回终点 @android:anim/anticipate_overshoot_interpolator AnticipateOvershootInterpolator
最后阶段弹球效果 @android:anim/bounce_interpolator BounceInterpolator
周期运动 @android:anim/cycle_interpolator CycleInterpolator
减速 @android:anim/decelerate_interpolator DecelerateInterpolator
匀速 @android:anim/linear_interpolator LinearInterpolator
 |

系统默认的插值器是AccelerateDecelerateInterpolator,即先加速后减速

  • 当在XML文件设置插值器时,只需传入对应的插值器资源ID即可
  • 当在Java代码设置插值器时,只需创建对应的插值器对象即可

小结

  1. 估值器(TypeEvaluator)决定 值 的具体变化数值
  2. 插值器(Interpolator)决定 值 的变化模式(匀速、加速blabla)

五、属性动画的监听器

ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法。

anim.addListener(new AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationCancel(Animator animation) {}
});

很多时候我们并不想要监听那么多个事件,可能我只想要监听动画结束这一个事件,那么每次都要将四个接口全部实现一遍就显得非常繁琐。没关系,为此Android提供了一个适配器类,叫作AnimatorListenerAdapter。由于AnimatorListenerAdapter中已经将每个接口都实现好了,所以这里不用实现任何一个方法也不会报错。我们可以单独重写我们需要的方法。

anim.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {}
});

六、XML编写动画

过去的补间动画除了使用代码编写之外也是可以使用XML编写的,因此属性动画也提供了这一功能,即通过XML来完成和代码一样的属性动画功能。

通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松,比如某个将通用的动画编写到XML里面,我们就可以在各个界面当中轻松去重用它。

如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:

  • 对应代码中的ValueAnimator
  • 对应代码中的ObjectAnimator
  • 对应代码中的AnimatorSet

使用xml实现上面的组合动画:把文件加载进来并将动画启动

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view);
animator.start();

参考资料

https://blog.csdn.net/guolin_blog/article/details/43816093
https://carsonho.blog.csdn.net/article/details/79860980

Android动画学习记录二(属性动画、估值器和插值器)相关推荐

  1. android动画详解二 属性动画原理

    property动画是一个强大的框架,它几乎能使你动画任何东西.你可以定义一个动画来改变对象的任何属性,不论其是否被绘制于屏幕之上.一个属性动画在一定时间内多次改变一个属性(对象的一个字段)的值.要动 ...

  2. Android动画学习记录一(Android动画种类、补间动画和帧动画)

    Android动画学习记录一(动画种类.补间动画和帧动画) 动画种类.补间动画和帧动画 Android动画学习记录一(动画种类.补间动画和帧动画) 一.动画种类 二.View动画 2.1 补间动画 补 ...

  3. Android动画框架(二)----属性动画

    转载请注明出处:http://blog.csdn.net/fishle123/article/details/50705928 Android提供三种形式动画:视图动画,帧动画,属性动画.其中属性动画 ...

  4. Unity学习记录——模型与动画

    Unity学习记录--模型与动画 前言 ​ 本文是中山大学软件工程学院2020级3d游戏编程与设计的作业7 编程题:智能巡逻兵 1.学习参考 ​ 除去老师在课堂上讲的内容,本次作业代码与操作主要参考了 ...

  5. Android绘制(三):Path结合属性动画, 让图标动起来!

    Android绘制(一):来用shape绘出想要的图形吧! Android绘制(二):来用Path绘出想要的图形吧! 目录 效果图 前言 绘制 属性动画 最后 效果图 不废话, 直接上效果图, 感兴趣 ...

  6. android 字母path动画,Android绘制(三):Path结合属性动画, 让图标动起来!

    目录 效果图 前言 绘制 属性动画 最后 效果图 不废话, 直接上效果图, 感兴趣再看下去. 其实不单单是效果图演示的, 运用熟练的话各种图标之间都是可以切换的. 暂停到终止 暂停到播放 前言 之前的 ...

  7. Android 之 动画合集之属性动画 -- 又见

    本节引言: 上节我们对Android的属性动画进行了初步的学习,相信大家对于属性动画已经不再是 一知半解的状态了,本节我们继续来探究Android属性动画的一些更高级的用法! 1.Evaluator自 ...

  8. 【Android 属性动画】属性动画 Property Animation 简介 ( 属性动画简介 | 属性动画特性 )

    文章目录 一.属性动画简介 二.属性动画特性 一.属性动画简介 属性动画简介 : 1.动画制作框架 : 属性动画系统 , 允许你 将任何可变的操作制作成动画 , 其功能很强大 ; 2.基本功能 : 使 ...

  9. Android 开发学习记录(4)---- httpclient使用(三)

    之前在Android 开发学习记录(3)---- httpclient使用(二)中介绍了如何使用httpclient访问需要账户登录的网址,当然首先是要有一个合法的登录账户. 但是现在好多网站在登录时 ...

最新文章

  1. Linux学习之三-Linux系统的一些重要配置文件
  2. java properties 保存_Java 读写Properties配置文件
  3. oracle ldap 配置,ldap 安装
  4. 原创精华:剖析亿级请求下的多级缓存
  5. ubuntu 软件包管理工具 dpkg,apt-get,aptitude 区别
  6. 虚拟机服务器被攻击,Linux服务器被攻击用来挖矿了
  7. spatial Statistics
  8. java自学难点_学习JAVA遇到的难点总结
  9. java存储整数,用于存储整数数值的是 JAVA四种整数数据类型的取值范围分别是多少...
  10. 服务器配置多个域名冲突
  11. 一代私募传奇落幕:黑石创始人彼得森留下4000亿美元离世
  12. 高斯混合模型聚类_高斯混合模型的解释及Python实现
  13. FireFly编辑器调用C语言,grasshopper的插件FireFly 萤火虫
  14. 使用Layui搭建后台管理界面
  15. Python学习笔记(7)文件读写2 Numpy
  16. 阮一峰:值得分享给开发者的 Authing 身份云
  17. ubuntu下 vim工具的安装与使用教程(一)
  18. 直通车推广有哪些容易被忽略的地方
  19. VSCode格式化XML
  20. 代码画验证码图片(一)

热门文章

  1. python属性访问权限_已拒绝Firefox驱动程序对“U”属性的访问权限
  2. 等待所有promise都完成,Promise.all()
  3. 关于召开“CIE2019第三届中国IT教育论坛”的通知
  4. 2022年安全员-A证考试题库及安全员-A证免费试题
  5. Foundations of Machine Learning 2nd——第二章 PAC学习框架 后记
  6. Python的编码解码
  7. IP地址的配置与运用,全网通
  8. PX4-Autopilot安装
  9. 微信小程序开发系列——注册申请
  10. android 自定义进度条矩形框,Android 自定义方形进度条