android 纯代码创建逐帧动画,Android开发补间动画、逐帧动画、属性动画

动画

一、补间动画(Tweened Animation)

作用对象:视图控件View

原理: 通过确定开始的视图样式以及结束的视图样式,中间的动画变化过程有系统补全来确定一个动画

优点:简单、方便,已封装好基础动画效果

缺点:仅控制整体实体效果,无法控制属性

动画样式: 平移动画(Translate)缩放动画(scale)旋转动画(rotate)透明度动画(alpha)

应用场景:视图中,标准、基础的动画效果。Activity,Fragment的切换效果。ViewGroup中子元素的出场效果

数值上的理解:从-100到100的值,以“%”结尾,表示百分比相对于自身;从-100到100的值,以“%p”结尾,表示百分比相对于父容器。例如平移开始位置在自身中间则是50%,如平时开始位置在父容器的则是50%p

1.平移动画(Translate)

TranslateAnimation类

示例代码:

android:duration = "3000"

android:fromXDelta="0"

android:toXDelta="300"

android:fillBefore = "false"

android:fillAfter = "true"

/>

如上代码中,虽然通过fillBefore,fillAfter设置了停留在动画之后,但是控件还是在原来位置,点击动画后的位置无反应。如果不设置fillBefore,fillAfter,动画结束后会还是显示在动画前的位置

Java代码中使用

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_second)

var translateAnim = AnimationUtils.loadAnimation(this,R.anim.view_anim)

tv_content.startAnimation(translateAnim)

tv_content.setOnClickListener {

Toast.makeText(this, "好的", Toast.LENGTH_SHORT).show()

}

}

纯Java代码:

var translateAnim = TranslateAnimation(0f,500f,0f,0f)

translateAnim.duration = 3000

tv_content.startAnimation(translateAnim)

2.缩放动画(Scale)

ScaleAnimation类

xml定义

android:fromXScale="0.0"

android:toXScale="1.4"

android:fromYScale="0.0"

android:toYScale="1.4"

android:pivotX="50%"

android:pivotY="50%"

android:duration = "3000">

注意:fromXScale和fromYScale都要写,pivotX只是改变开始缩放的始点,不加缩放的始点是view的左上角,

android:pivotX="50"是控件view的x方向上加50像素

android:pivotX="50%"是控件view的x方向上加view控件宽的50%

android:pivotX="50%p"是控件view的x方向上加父布局控件宽的50%

3.旋转动画(Rotate)

RotateAnimation类

android:fromDegrees="0"

android:toDegrees="180"

android:duration = "2000"

android:pivotX="50%"

android:pivotY="50%"

/>

android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)

4.透明度动画(Alpha)

AlphaAnimation类

android:fromAlpha="1.0"

android:toAlpha="0.0"

android:duration = "2000">

Activity的切换效果

实现效果从右向左滑动

in_from_right.xml

android:duration = "500"

android:fromXDelta="100%p"

android:toXDelta="0%p"

/>

out_to_left.xml

>

android:duration="500"

android:fromXDelta="0%p"

android:toXDelta="-100%p"

/>

一般用在Activity的成对出现,但至少保持动画时间是一样的

首先要了解Activity的位置

x = 0%p是代表Activity刚好在屏幕中间

x = 100%p是代表Activity在屏幕的右侧

x = -100%p是代表Activity在屏幕的左侧

Fragment的切换效果(几乎用不到)

// 采用`FragmentTransavtion`的 setCustomAnimations()进行设置

FragmentTransaction fragmentTransaction = mFragmentManager

.beginTransaction();

fragmentTransaction.setCustomAnimations(

R.anim.in_from_right,

R.anim.out_to_left);

// 此处的自定义动画效果同Activity,此处不再过多描述

组合动画

采用< Set/>标签

监听动画

anim.addListener(new AnimatorListenerAdapter() {

// 向addListener()方法中传入适配器对象AnimatorListenerAdapter()

// 由于AnimatorListenerAdapter中已经实现好每个接口

// 所以这里不实现全部方法也不会报错

@Override

public void onAnimationStart(Animator animation) {

// 如想只想监听动画开始时刻,就只需要单独重写该方法就可以

}

});

二、逐帧动画(Frame Animation)

作用对象:视图控件View

原理:将动画拆分为帧的形式,且定义每一帧是一张图片,按顺序播放

特点:优点:简单、方便

缺点:容易引起OOM,因会用大量以及尺寸较大的图片资源

应用场景: 较为复杂的个性化动画效果

三、属性动画(Property Animation)

作用对象:任意Java对象

原理: 在一定时间间隔内,通过不断改变值以及赋值给对象的属性,从而实现该对象在该属性上的动画效果

特点:优点:作用对象进行了拓展:不只是View对象,甚至无对象也可以,不只是4种基本变换,还有其他动画效果

缺点:用起来稍微复杂点

应用场景: 与属性相关、更加复杂的动画效果,比如通过改变View的颜色属性达到的动画效果

逐帧动画和补间动画存在一定的缺点:

1:作用对象局限于View

即补间动画只能作用View上,没法对非View的对象进行操作。有些情况的动画效果只是视图的某个属性,比如通过视图的颜色动态变化,从而实现动画效果,而不是针对整个View视图进行动画操作

2:没有改变View的属性,只是改变视觉效果

如移动View,虽然看起来View的位置变了,但实际没变,还是原来的

3:动画效果单一

补间动画只能实现平移、旋转、缩放 & 透明度这些简单的动画需求,一旦遇到相对复杂的动画效果,即超出了上述4种动画效果,那么补间动画则无法实现

ValueAnimator类

原理:通过不断控制值的变化,再不断手动赋给对象的属性,从而实现动画效果

Java代码:正常流程

Log.i("tv_content",tv_content.width.toString()+"\t"+tv_content.layoutParams.width)

//value动画

val valueAnimator = ValueAnimator.ofInt(tv_content.layoutParams.width,500)

valueAnimator.duration = 2000

valueAnimator.addUpdateListener {

val currentValue:Int = it.animatedValue as Int

println(currentValue)

//获取不断改变的值给view相应的属性

tv_content.layoutParams.width = currentValue

tv_content.requestLayout()

}

valueAnimator.start()

在xml中定义

android:valueFrom="0"

android:valueTo="100"

android:valueType="intType"

android:duration="2000"

/>

java用xml中定义的

//用xml的value动画

var valueAnimator = AnimatorInflater.loadAnimator(this,R.animator.value_anim)

valueAnimator.setTarget(tv_content)

valueAnimator.start()

注:有点坑地方补间动画xml的文件夹名是anim,属性动画是animator。第二单纯这样setTarget(view)是没用的,它不知道改变什么属性。

所以用属性动画还是用java代码定义写方便

对象:ValueAnimator.ofObject()

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

需我们自定义TypeEvaluator来告知系统如何进行从初始对象过渡到结束对象的逻辑

示例PointEvaluator.java

// 实现TypeEvaluator接口

public class PointEvaluator implements TypeEvaluator {

// 复写evaluate()

// 在evaluate()里写入对象动画过渡的逻辑

@Override

public Object evaluate(float fraction, Object startValue, Object endValue) {

// 将动画初始值startValue 和 动画结束值endValue 强制类型转换成Point对象

Point startPoint = (Point) startValue;

Point endPoint = (Point) endValue;

// 根据fraction来计算当前动画的x和y的值

float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());

float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());

// 将计算后的坐标封装到一个新的Point对象中并返回

Point point = new Point(x, y);

return point;

}

}

估值器(TypeEvaluator)

作用:设置动画 如何从初始值 过渡到 结束值 的逻辑

ObjectAnimator类

是ValueAnimator的子类

是通过反射找到相应的set函数

原理:通过不断控制值的变化,再不断自动赋给对象的属性,从而实现动画效果

示例代码:

ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationX",0,270,0);

animator.setDuration(2000);

animator.start();

怎么知道哪些属性是能赋值改变形成动画的呢

1、要使用ObjectAnimator来构造对画,要操作的控件中,必须存在对应的属性的set方法

2、setter 方法的命名必须以骆驼拼写法命名,即set后每个单词首字母大写,其余字母小写,即类似于setPropertyName所对应的属性为propertyName

简单来说:先找View的set相应属性试试,有,就把属性开头大写改为小写即可

自定义ObjectAnimator属性

public class MyPointView extends View {

private PointRadius mPoint = new PointRadius(100);

public MyPointView(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (mPoint != null) {

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setColor(Color.RED);

paint.setStyle(Paint.Style.FILL);

canvas.drawCircle(300, 300, mPoint.getRadius(), paint);

}

}

void setPointRadius(int radius) {

mPoint.setRadius(radius);

invalidate();

}

}

关键setPointRadius方法

使用:

val objectAnimator = ObjectAnimator.ofInt(my_point_view,"pointRadius",0,300,200)

objectAnimator.duration = 2000

objectAnimator.start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值