Android动画开发思路

1 篇文章 0 订阅
1 篇文章 1 订阅

传统动画实现

1、不建议使用,性能差;帧动画采用播放序列帧图实现,容易造成OOM并且APK过大;
GIF,Gif大小是bodymovin JSON的两倍以上,并且以固定大小呈现,无法按比例缩放以匹配大型和高密度屏幕;
使用视频,这种方式当然可以,但是一般来说宣传片才用的上视频,一般的动画远不需要用视频才能实现的,未
免有些大材小用了,而且占用空间依然很大

2、属性动画是对对象属性的动画,补间动画都可以使用属性动画实现,如alpha、scalex等,如:

ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 0.0f, 1.0f);
属性动画优化,参考https://blog.csdn.net/iblade/article/details/82260435:
float currentX = textView.getTranslationX();
float currentY = textView.getTranslationY();
//传统写法
ObjectAnimator tX = ObjectAnimator.ofFloat(textView, "translationX", currentX, -300, currentX);
ObjectAnimator tY = ObjectAnimator.ofFloat(textView, "translationY", currentY, 200, currentY);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(tX, tY);//或者  set.play(tX).with(tY);
set.start();
//一个view同时发生多种效果时,建议使用PropertyValuesHolder,这样ObjectAnimator只有一个对象
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX", currentX, 500, currentX);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY", currentY, 400, currentY);
ObjectAnimator.ofPropertyValuesHolder(textView, pvhX, pvhY).setDuration(1000).start();

3、补间动画分为四种形式,分别是 alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转)。
补间动画的实现,一般会采用xml 文件的形式:如:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toAlpha="0.0" />
	
animation = new RotateAnimation(-deValue, deValue, Animation.RELATIVE_TO_SELF,
        pxValue, Animation.RELATIVE_TO_SELF, pyValue);

高级动画开发

1、第三方库 Lottie加载AE 插件Bodymovin导出的json文件,优点处理复杂动画相对帧动画或者png更小,使用加载简单,只加载一次可以重复使用
如一个列表内item点赞动画;可以动态的根据应用状态改变动画的值或者黑白主题,参考http://airbnb.io/lottie/#/android,json效果预览https://lottiefiles.com/preview
例:

<com.airbnb.lottie.LottieAnimationView
        android:id="@+id/welcome_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        app:lottie_fileName="welcomeTitle.json"
        app:lottie_loop="false"
        app:lottie_autoPlay="true" />

2、Facebook关键帧。关键帧是Facebook提供的一个出色的新库,可用于响应。但是,关键帧不支持Lottie的某些功能,例如蒙版,遮罩,修剪路径,虚线图案等
使用After Effects开发动画效果,Keyframes是在lottile json这个基础上又抽取了它需要的元素,Keyframes也因此大大降低了json文件大小
使用Keyframes库开发动画效果有一个详细的约束条件清单,具体内容请点击参考link
例:

InputStream stream = getResources().getAssets().open("asset_name");
KFImage kfImage = KFImageDeserializer.deserialize(stream);
Drawable kfDrawable = new KeyframesDrawableBuilder().withImage(kfImage).build();
ImageView imageView = (ImageView)findViewById(R.id.some_image_view);
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
imageView.setImageDrawable(kfDrawable);

kfDrawable.startAnimation();
//Stops the animation when the current animation ends
kfDrawable.stopAnimationAtLoopEnd();

参考参考link1参考link2

3、使用Bodymovin导出AndroidVectorDrawable xml并使用Android SDK进行播放,在 AfterEffects 中,选择 窗口 → 扩展 → Bodymovin
选中要导出的动画作品然后打开它的设置
选择 AVD 选项
选择一个目标文件夹然后点击渲染
在输出文件夹中,在标准的 Bodymovin 导出的 data.json 文件旁边,你会找到一个新的 data.xml 文件——这就是 AnimatedVectorDrawable 文件(使用内联的资源文件)
将这个文件拖动到 Android 项目,参考link,性能更高,因为它在RenderThread而不是主线程上运行。仅支持Lottie功能的子集。
无法手动设置进度。不支持文字或动态颜色。无法以编程方式或通过互联网加载。
例:

<ImageView
        android:id="@+id/test_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/header"
        android:layout_marginTop="200dp"
        android:layout_centerHorizontal="true"
        android:scaleType="center"
        android:src="@drawable/fingerprint0430"/>
ImageView test = findViewById(R.id.test_image);
        ((Animatable) (test.getDrawable())).start();

4、在属性动画的基础上升级,自定义动画的实现思路(机器人摇头眨眼)
Imageview 配合 继承ValueAnimator(外部实现一个匀速变化的时间点) + 实现onAnimationUpdate获取不同时间点的自定义drawable
自定义继承drawable ,onAnimationUpdate时候调用update并invalidateSelf,触发drawable draw(canvas)方法,从而计算出当前时间点bitmap的状态
运用Matrix矩阵变换(setRotate,postTranslate顺序会影响结果,矩阵的算法决定),canvas.save()和canvas.restore()必须配合一起使用
多个部分的动画采用分别继承drawable,单个部位的drawable对应的多个动画采用分时间段处理。

5、vector和animated-vector,svg矢量图转换为vector(包含path、group信息),然后新建animated-vector对vector的group name块设置animation,
例:

<vector android:height="24dp" android:tint="#C374FF"
    android:viewportHeight="24.0" android:viewportWidth="24.0"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector_drawable_progress_horizontal_trimmed" >
    <target
        android:name="rect2_grp"
        android:animation="@animator/progress_horizontal_rect2" />
    <target
        android:name="rect1_grp"
        android:animation="@animator/progress_horizontal_rect1" />
</animated-vector>

原理和使用方法同2,屏幕适配和兼容性是一个问题

对接动效设计师

1、针对动画实现的容易程度看给什么样的参数或文件,简单的直接给时间轴+各属性变化即可,一般使用贝塞尔曲线插值器(方便调动效的变化效果);
2、复杂的需要根据状态显示不同效果的动效,建议使用Bodymovin导出的json动效文件,工程师直接使用lottile加载动效,并根据状态动态修改属性值;
3、复杂的且固定的动效,建议直接使用使用Bodymovin导出AndroidVectorDrawable xml,文件更小,Android加载渲染效果更佳。

动画参考:https://zhuanlan.zhihu.com/p/74868076

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值