欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 运维知识 > android >内容正文

android

android image 位移动画-凯发k8官方网

发布时间:2024/10/14 android 32 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 android image 位移动画_深入理解android之动画 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

android 里动画从用途上讲,可以分为三类view animation(view动画)又称 tween animation(补间动画)、drawable animation(帧动画) 和 property animation(属性动画)。 这篇文章,我就介绍一下这三种类型的动画。

目录:

(一)view动画

view动画是基于view的渐变动画,只改变了view的绘制效果,view的实际属性值并未改变。

view动画的对象是view,它支持4种动画效果:

translateanimation(平移动画)

scaleanimation(缩放动画)

rotateanimation(旋转动画)

alphaanimation(透明度动画)

并提供了animationset动画集合。实现原理是每次绘图时view所在的viewgroup中的dispathdraw,流程如下图:

        

除了这四种典型的动画效果外,帧动画本质上也属于view动画。但是帧动画的表现形式和这4种动画不太一样,因此通常单拎出来归为一类。

这四种动画既可以通过xml来定义,也可以通过代码来动态创建。

使用xml之前我们首先需要创建xml文件,路径为:res/anim/filename.xml。

1. 透明度动画

代码实现:alphaanimation animation = new alphaanimation(0, 1);// 透明度0变化到透明度为1

animation.setduration(1000);// 动画执行时间1s

textview.startanimation(animation);

xml实现:

android:duration="1000"

android:fromalpha="0"

android:interpolator="@android:anim/accelerate_interpolator"

android:repeatcount="3"

android:fillafter="true"

android:repeatmode="restart"

android:toalpha="1" />

2. 旋转动画

代码实现:rotateanimation animation = new rotateanimation(0, 360, 100, 100);

animation.setduration(1000);

animation.setfillafter(true); // 设置保持动画最后的状态

animation.setinterpolator(new accelerateinterpolator()); // 设置插入器

textview.startanimation(animation);

还可以通过系统提供参数来控制动画

new rotateanimation(0f, 360f, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);

xml实现:

android:duration="1000"

android:fromdegrees="0.0"

android:interpolator="@android:anim/linear_interpolator"

android:pivotx="50.0%"

android:pivoty="50.0%"

android:repeatcount="infinite"

android:todegrees="360.0">

参数

说明fromdegrees

为动画起始时的旋转角度,此角度是当前为0及360,设置其他值则先跳至该角度的位置再由from - to的值: 负则正向转,正则反向转

todegrees

为动画旋转到的角度

pivotxtype

为动画在x轴相对于物件位置类型

pivotxvalue

为动画相对于物件的x坐标的开始位置,此值是以本身原始位置为原点,即如设为20%p,则向右移动父控件的20%位移,为负数则向左移

pivotytype

为动画在y轴相对于物件位置类型

pivotyvalue

为动画相对于物件的y坐标的开始位置,此值是以本身原始位置为原点,即如设为20%p,则向下移动父控件的20%位移,为负数则向上移

3. 位移动画

代码实现:translateanimation translateanimation = new translateanimation(0, 200, 0, 200);

translateanimation.setduration(1000);

textview.startanimation(translateanimation);

xml实现:

android:duration="1000"

android:fillafter="true"

android:fromxdelta="0"

android:fromydelta="0"

android:repeatcount="3"

android:toxdelta="200"

android:toydelta="000">

参数

说明fromxdelta

为动画起始时 x坐标上的移动位置

toxdelta

为动画结束时 x坐标上的移动位置

fromydelta

为动画起始时y坐标上的移动位置

toydelta

为动画结束时y坐标上的移动位置

4. 缩放动画

代码实现:scaleanimation animation = new scaleanimation(0,1,0,1);

animation.setduration(1000);

textview.startanimation(animation);

缩放动画也可以设置缩放的中心点

scaleanimation animation = new scaleanimation(0, 1, 0, 1, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);

xml实现:

android:duration="1000"

android:fillafter="true"

android:fillbefore="true"

android:fromxscale="0.0"

android:fromyscale="0.0"

android:interpolator="@android:anim/linear_interpolator"

android:pivotx="50%"

android:pivoty="50%"

android:repeatcount="-1"

android:repeatmode="reverse"

android:startoffset="2000"

android:toxscale="1.0"

android:toyscale="1.0">

参数

说明fromx

为动画起始时 x坐标上的伸缩尺寸 0.0表示收缩到没有

tox

为动画结束时 x坐标上的伸缩尺寸 1.0表示正常无伸缩

fromy

为动画起始时y坐标上的伸缩尺寸 值小于1.0表示收缩

toy

为动画结束时y坐标上的伸缩尺寸 值大于1.0表示放大

pivotxtype

为动画在x轴相对于物件位置类型

pivotxvalue

为动画相对于物件的x坐标的开始位置

pivotxtype

为动画在y轴相对于物件位置类型

pivotyvalue

为动画相对于物件的y坐标的开始位置

5. anim文件使用

animation animation = animationutils.loadanimation(this, r.anim.alpha_anim);

textview.startanimation(animation);

6. 动画集合

animationset提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。

animationset animationset = new animationset(true);

animationset.setduration(1000);

alphaanimation alpha=new alphaanimation(0,1);

alpha.setduration(1000);

animationset.addanimation(alpha);

translateanimation translate = new translateanimation(100, 200, 0, 200);

translate.setduration(1000);

animationset.addanimation(translate);

textview.startanimation(animationset);

7. 动画监听

对于动画事件,android也提供了开始、结束和重复事件的监听方法。

animation.setanimationlistener(new animation.animationlistener() {

@override

public void onanimationstart(animation animation) {

}

@override

public void onanimationend(animation animation) {

}

@override

public void onanimationrepeat(animation animation) {

}

});

8. view动画的特殊使用

(1)layoutanimation

layoutanimation作用于viewgroup,为viewgroup制定一个动画,他的每个子元素都会按照这种动画出场。这种效果常被用在listview上。使用步骤如下:

1)定义layoutanimation

android:delay="0.5"

android:animationorder="reverse"

android:animation="@anim/animation_scale">

android:delay             表示子元素开始动画的时间延迟

android:animationorder         表示子元素动画的顺序,有三个选项:

normal:顺序显示

reverse:表示逆向显示

random:随机播放

android:animation        为子元素指定具体的入场动画

2)为子元素制定具体的入场动画

android:fromxscale="0.1"

android:toxscale="1.5"

android:fromyscale="0.1"

android:toyscale="1.5"

android:duration="2000">

3)为groupview指定layoutanimation属性

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@ id/xlv"

android:layoutanimation="@anim/animation_layout"

android:background="#fff4f7f9"

android:divider="#ddd"

android:dividerheight="1.0px"

android:listselector="#999">

除了在xml文件中进行设置,我们还可以使用代码来完成:

animation animation = animationutils.loadanimation(this, r.anim.anim_item);

layoutanimationcontroller controller = new layoutanimationcontroller(animation);

controller.setdelay(0.5f);

controller.setorder(layoutanimationcontroller.order_normal);

listview.setlayoutanimation(controller);

(2)transition animation(过渡动画)

transition也是基于属性动画的,与属性动画不同的是,它是可以实现布局改变的过渡动画。由于transition的内容较多,具体请参照

(二)帧动画

帧动画就是加载一系列drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放,就像电影胶片。在代码中定义动画帧,使用animationdrawable类;xml文件能更简单的组成动画帧,在res/drawable文件夹,使用采用来定义不同的帧。只能设置的属性是动画间隔时间。

android:oneshot="false">

...

然后对组件的属性(如imageview的android:src/android:background)直接设置即可。

imageview iv = findviewbyid(r.id.image_view);

//iv.setbackgroundresource(r.drawable.drawable_animation);

//获取背景,并将其强转成animationdrawable

animationdrawable animationdrawable = (animationdrawable) iv.getbackground();

//判断是否在运行

if(!animationdrawable.isrunning()){

//开启帧动画

animationdrawable.start();

}

注意:帧动画的使用非常简单,但是比较容易引起oom,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片。

(三)属性动画

属性动画的对象除了传统的view对象,还可以是object对象,动画之后,属性值被实实在在的改变了。因此,属性动画能够通过改变view对象的实际属性来实现view动画。任何时候view属性的改变,view能自动调用invalidate()来刷新。

属性动画是在 android 3.0 开始引入的新的动画形式,不过说它新只是相对的,它已经有好几年的历史了,而且现在的项目中的动画 99% 都是用的它,极少再用到 view animation 了。属性动画不仅可以使用自带的 api 来实现最常用的动画,而且通过自定义 view 的方式来做出定制化的动画。

1. viewpropertyanimator

使用方式:

view.animate() 后跟 translationx() 等方法,动画会自动执行。

view.animate().translationx(500);

2. objectanimator

使用方式:

如果是自定义控件,需要添加 setter / getter 方法;

用 objectanimator.ofxxx() 创建 objectanimator 对象;

用 start() 方法执行动画。public class sportsview extends view {

float progress = 0;

......

// 创建 getter 方法

public float getprogress() {

return progress;

}

// 创建 setter 方法

public void setprogress(float progress) {

this.progress = progress;

invalidate();

}

@override

public void ondraw(canvas canvas) {

super.ondraw(canvas);

......

canvas.drawarc(arcrectf, 135, progress * 2.7f, false, paint);

......

}

}

......

// 创建 objectanimator 对象

objectanimator animator = objectanimator.offloat(view, "progress", 0, 65);

// 执行动画

animator.start();

3. 通用功能

(1)setduration(int duration) 设置动画时长

(2)setinterpolator(interpolator interpolator) 设置 interpolator(插值器)

acceleratedecelerateinterpolator  先加速再减速  (默认的 interpolator)

linearinterpolator  匀速

accelerateinterpolator  持续加速

decelerateinterpolator  持续减速直到 0

anticipateinterpolator  先回拉一下再进行正常动画轨迹

overshootinterpolator  动画会超过目标值一些,然后再弹回来

anticipateovershootinterpolator  上面这两个的结合版:开始前回拉,最后超过一些然后回弹

bounceinterpolator  在目标值处弹跳

cycleinterpolator  这个也是一个正弦 / 余弦曲线

fastoutlinearininterpolator  用贝塞尔曲线持续加速

linearoutslowininterpolator  持续减速,初始速度更高

pathinterpolator  自定义动画完成度 / 时间完成度曲线path interpolatorpath = new path();

...

// 匀速

interpolatorpath.lineto(1, 1);

(3)setlistener() / objectanimator.addlistener()  设置监听器

参数类型是 animatorlistener,所以本质上其实都是一样的。 animatorlistener共有 4 个回调方法:

onanimationstart(animator animation)

onanimationend(animator animation)

onanimationcancel(animator animation)

onanimationrepeat(animator animation)

补充:setupdatelistener() /addupdatelistener()

和上面两个方法类似,但是这两个方法虽然名称和可设置的监听器数量不一样,但本质其实都一样的。它们的参数都是 animatorupdatelistener。它只有一个回调方法:

onanimationupdate(valueanimator animation)

4. typeevaluator

关于 objectanimator,可以用 ofint() 来做整数的属性动画和用 offloat() 来做小数的属性动画。这两种属性类型是属性动画最常用的两种,不过在实际的开发中,可以做属性动画的类型还是有其他的一些类型。当需要对其他类型来做属性动画的时候,就需要用到 typeevaluator 了。

(1)argbevaluator

typeevaluator 最经典的用法是使用 argbevaluator 来做颜色渐变的动画。

objectanimator animator = objectanimator.ofint(view, "color", 0xffff0000, 0xff00ff00);

animator.setevaluator(new argbevaluator());

animator.start();

在 android 5.0 (api 21) 加入了新的方法 ofargb()。

objectanimator animator = objectanimator.ofargb(view, "color", 0xffff0000, 0xff00ff00);

animator.start();

(2)自定义 evaluator

// 自定义 hslevaluator

private class hsvevaluator implements typeevaluator {

float[] starthsv = new float[3];

float[] endhsv = new float[3];

float[] outhsv = new float[3];

@override

public integer evaluate(float fraction, integer startvalue, integer endvalue) {

// 把 argb 转换成 hsv

color.colortohsv(startvalue, starthsv);

color.colortohsv(endvalue, endhsv);

// 计算当前动画完成度(fraction)所对应的颜色值

if (endhsv[0] - starthsv[0] > 180) {

endhsv[0] -= 360;

} else if (endhsv[0] - starthsv[0] < -180) {

endhsv[0] = 360;

}

outhsv[0] = starthsv[0] (endhsv[0] - starthsv[0]) * fraction;

if (outhsv[0] > 360) {

outhsv[0] -= 360;

} else if (outhsv[0] < 0) {

outhsv[0] = 360;

}

outhsv[1] = starthsv[1] (endhsv[1] - starthsv[1]) * fraction;

outhsv[2] = starthsv[2] (endhsv[2] - starthsv[2]) * fraction;

// 计算当前动画完成度(fraction)所对应的透明度

int alpha = startvalue >> 24 (int) ((endvalue >> 24 - startvalue >> 24) * fraction);

// 把 hsv 转换回 argb 返回

return color.hsvtocolor(alpha, outhsv);

}

}

objectanimator animator = objectanimator.ofint(view, "color", 0xff00ff00);

// 使用自定义的 hslevaluator

animator.setevaluator(new hsvevaluator());

animator.start();

(3)使用不限定类型的属性做动画

借助于 typeevaluator,属性动画就可以通过 ofobject() 来对不限定类型的属性做动画了。

1)为目标属性写一个自定义的 typeevaluator

2)使用 ofobject() 来创建 animator,并把自定义的 typeevaluator 作为参数填入

private class pointfevaluator implements typeevaluator {

pointf newpoint = new pointf();

@override

public pointf evaluate(float fraction, pointf startvalue, pointf endvalue) {

float x = startvalue.x (fraction * (endvalue.x - startvalue.x));

float y = startvalue.y (fraction * (endvalue.y - startvalue.y));

newpoint.set(x, y);

return newpoint;

}

}

objectanimator animator = objectanimator.ofobject(view, "position",

new pointfevaluator(), new pointf(0, 0), new pointf(1, 1));

animator.start();

5. propertyvaluesholder

很多时候,我们需要在同一个动画中改变多个属性,例如在改变透明度的同时改变尺寸。如果使用 viewpropertyanimator,你可以直接用连写的方式来在一个动画中同时改变多个属性。

view.animate()

.scalex(1)

.scaley(1)

.alpha(1);

而对于 objectanimator,是不能这么用的。不过你可以使用 propertyvaluesholder 来同时在一个动画中改变多个属性。

propertyvaluesholder holder1 = propertyvaluesholder.offloat("scalex", 1);

propertyvaluesholder holder2 = propertyvaluesholder.offloat("scaley", 1);

propertyvaluesholder holder3 = propertyvaluesholder.offloat("alpha", 1);

objectanimator animator = objectanimator.ofpropertyvaluesholder(view, holder1, holder2, holder3)

animator.start();

6. animatorset

有的时候,我们不止需要在一个动画中改变多个属性,还会需要多个动画配合工作,比如,在内容的大小从 0 放大到 100% 大小后开始移动。这种情况使用 propertyvaluesholder 是不行的,因为这些属性如果放在同一个动画中,需要共享动画的开始时间、结束时间、interpolator 等一系列的设定,这样就不能有先后次序地执行动画了。这就需要用到 animatorset 了。

objectanimator animator1 = objectanimator.offloat(...);

animator1.setinterpolator(new linearinterpolator());

objectanimator animator2 = objectanimator.ofint(...);

animator2.setinterpolator(new decelerateinterpolator());

animatorset animatorset = new animatorset();

// 两个动画依次执行

animatorset.playsequentially(animator1, animator2);

animatorset.start();

animatorset 还可以这么用:

// 两个动画同时执行

animatorset.playtogether(animator1, animator2);

animatorset.start();

以及这么用:

// 使用 animatorset.play(animatora).with/before/after(animatorb)

// 的方式来精确配置各个 animator 之间的关系

animatorset.play(animator1).with(animator2);

animatorset.play(animator1).before(animator2);

animatorset.play(animator1).after(animator2);

animatorset.start();

7. propertyvaluesholders.ofkeyframe()

除了合并多个属性和调配多个动画,你还可以在 propertyvaluesholder 的基础上更进一步,通过设置 keyframe (关键帧),把同一个动画属性拆分成多个阶段。例如,你可以让一个进度增加到 100% 后再「反弹」回来。

// 在 0% 处开始

keyframe keyframe1 = keyframe.offloat(0, 0);

// 时间经过 50% 的时候,动画完成度 100%

keyframe keyframe2 = keyframe.offloat(0.5f, 100);

// 时间见过 100% 的时候,动画完成度倒退到 80%,即反弹 20%

keyframe keyframe3 = keyframe.offloat(1, 80);

propertyvaluesholder holder = propertyvaluesholder.ofkeyframe("progress", keyframe1, keyframe2, keyframe3);

objectanimator animator = objectanimator.ofpropertyvaluesholder(view, holder);

animator.start();

总结:「关于复杂的属性关系来做动画」,就这么三种:

使用 propertyvaluesholder 来对多个属性同时做动画;

使用 animatorset 来同时管理调配多个动画;

propertyvaluesholder 的进阶使用:使用 propertyvaluesholder.ofkeyframe() 来把一个属性拆分成多段,执行更加精细的属性动画。

fighting_初心

发布了37 篇原创文章 · 获赞 38 · 访问量 1万

私信

关注

来源:https://www.icode9.com/content-4-622551.html

总结

以上是凯发k8官方网为你收集整理的android image 位移动画_深入理解android之动画的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图