View动画和属性动画
在应用中, 动画效果提升用户体验, 主要分为View动画和属性动画. View动画变换场景图片效果, 效果包括平移(translate), 缩放(scale), 旋转(rotate), 透明(alpha); 属性动画动态地改变改变属性, 达到动画效果. 本文包含源码.
Animation
本文源码的GitHub下载地址
View动画
动画包含四种平移, 缩放, 旋转, 透明, 也支持组合使用.
mAnimations = new ArrayList<>();
mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_translate));
mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_scale));
mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_rotate));
mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_alpha));
mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_all));
平移动画: duration
持续时间; fromXDelta
起始X坐标, fromYDelta
起始Y坐标; toXDelta
终止X坐标, toYDelta
终止Y坐标.
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="@android:anim/accelerate_interpolator">
<!--平移动画-->
<translate
android:duration="2000"
android:fromXDelta="50"
android:fromYDelta="-100"
android:toXDelta="0"
android:toYDelta="0"/>
</set>
fillAfter
动画完成后停留, 即在平移后不复原;interpolator
变换插值器.
缩放动画: fromXScale
起始宽度比例, fromYScale
起始高度比例; toXScale
终止宽度比例,toYScale
终止高度比例.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--缩放动画-->
<scale
android:duration="2000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="1.0"
android:toYScale="1.0"/>
</set>
旋转动画: fromDegrees
起始角度, toDegrees
终止角度; pivotX
旋转中心X坐标, pivotY
旋转中心Y坐标.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!--旋转动画-->
<rotate
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-720"/>
</set>
透明动画: fromAlpha
起始透明度, toAlpha
终止透明度.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--透明动画-->
<alpha
android:duration="2000"
android:fromAlpha="0.1"
android:toAlpha="1.0"/>
</set>
组合动画: 融合平移, 缩放, 旋转, 透明四种动画, 效果是图片旋转着从左上角滚入屏幕, 逐渐变大变清晰.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000">
<!--平移动画-->
<translate
android:fromXDelta="50"
android:fromYDelta="-100"
android:toXDelta="0"
android:toYDelta="0"/>
<!--缩放动画-->
<scale
android:duration="2000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="1.0"
android:toYScale="1.0"/>
<!--旋转动画-->
<rotate
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-720"/>
<!--透明动画-->
<alpha
android:duration="2000"
android:fromAlpha="0.1"
android:toAlpha="1.0"/>
</set>
帧动画: 特殊动画, 不断变换图片, 模拟动画效果. animation-list
动画列表, 每个item
表示一个图片, duration
是图片停留时间. oneshot
值是true持续一次, false不断循环.
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<!--循环显示三个图片-->
<item
android:drawable="@drawable/seo_square"
android:duration="250"/>
<item
android:drawable="@drawable/kim_square"
android:duration="250"/>
<item
android:drawable="@drawable/sunny_square"
android:duration="250"/>
</animation-list>
自定义动画: 重载initialize
和applyTransformation
方法. initialize
初始化动画;applyTransformation
应用转换, 参数interpolatedTime
表示差值次数.
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
public Rotate3dAnimation(
float fromDegrees, float toDegrees,
float centerX, float centerY,
float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); // 结尾度数
// 中心点
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save(); // 照相机
// Z轴平移
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees); // Y轴旋转
camera.getMatrix(matrix);
camera.restore();
// View的中心点进行旋转
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerX);
super.applyTransformation(interpolatedTime, t);
}
}
RecyclerList的项也支持动画式插入.
@Override public void onBindViewHolder(final GridViewHolder holder, final int position) {
// ...
setAnimation(holder.getContainer(), position);
}
private void setAnimation(View viewToAnimate, int position) {
if (position > mLastPosition || mLastPosition == -1) {
Animation animation = AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
mLastPosition = position;
}
}
属性动画
属性动画通过变换对象属性, 实现动画效果, 对应属性必须含有set和get方法, 支持调用. 对于自定义的属性, 则使用Wrapper或插值方式.
属性动画仅支持API 11以上版本, 以前版本使用支持库.
Wrapper: 根据View的变换属性, 提供宽度(width)的设置(set)与获取(get).
private void performWrapperAnimation(final View view, final int start, final int end) {
ViewWrapper vw = new ViewWrapper(view);
ObjectAnimator.ofInt(vw, "width", start, end).setDuration(2000).start(); // 启动动画
}
// 视图包装, 提供Width的get和set方法
private static class ViewWrapper {
private View mView;
public ViewWrapper(View view) {
mView = view;
}
@SuppressWarnings("unused")
public int getWidth() {
return mView.getLayoutParams().width;
}
@SuppressWarnings("unused")
public void setWidth(int width) {
mView.getLayoutParams().width = width;
mView.requestLayout();
}
}
requestLayout: 当View确定自身不再适合现有区域时, 调用requestLayout, 要求Parent View重新调用onMeasure和onLayout重新设置当前View的位置.
特别当View的LayoutParams发生改变时, 并且值还未应用至View上, 这时候适合调用此方法.
invalidate: View本身调用迫使View重绘.
差值: 使用ValueAnimator(属性动画), 并设置更新, 添加IntEvaluator(整数估值器), 渐进地设置View的宽度.
private void performListenerAnimation(final View view, final int start, final int end) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
// 持有一个IntEvaluator对象,方便下面估值的时候使用
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 获得当前动画的进度值,整型,1-100之间
int currentValue = (Integer) animator.getAnimatedValue();
// 获得当前进度占整个动画过程的比例,浮点型,0-1之间
float fraction = animator.getAnimatedFraction();
// 直接调用整型估值器通过比例计算出宽度,然后再设给Button
view.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
view.requestLayout();
}
![
![
![ezgif.com-b9f6ca81b1.gif](https://user-gold-cdn.xitu.io/2017/1/4/5cba3a11357c16ea9129f9c7a6b9f1cc)
](http://upload-images.jianshu.io/upload_images/749674-cdf2dd08094b34fa.gif?imageMogr2/auto-orient/strip)
](http://upload-images.jianshu.io/upload_images/749674-a45e2ffca44d4f79.gif?imageMogr2/auto-orient/strip)
});
valueAnimator.setDuration(2000).start();
}
注意LayoutParams的数值是px像素, 需要dp转换px.
效果
效果
应用使用动画, 提升用户体验, 但要注意性能. 大量使用图片可能导致OOM; 循环动画无法释放可能产生内存泄露; 注意px与dp之间的转换.
OK, that's all! Enjoy it!
View动画和属性动画的更多相关文章
- Android开发——View动画、帧动画和属性动画详解
0. 前言 Android动画是面试的时候经常被问到的话题.我们都知道Android动画分为三类:View动画.帧动画和属性动画. 先对这三种动画做一个概述: View动画是一种渐进式动画,通过图 ...
- android 学习随笔二十六(动画:属性动画)
属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...
- Android开发实战之补间动画和属性动画
说起动画,其实一点也不陌生,在使用一款app的时候为了优化用户体验,多多少少的,都会加入动画. 安卓中的动画,分为两大类:补间动画和属性动画.本篇博文会详细介绍总结这两大动画,希望本篇博文对你的学习和 ...
- Android动画基础——属性动画(Property Animation)
本篇涉及例子下载:Github 本篇讲android 3.0引入的属性动画框架,上篇写视图动画View Animation时就说过ViewAnimation的缺点,那就是动画作用的是view本身的视觉 ...
- View体系之属性动画
(内容省略了valueAnimator和PropertyValueHolder使用) 属性动画的使用的主要方式是AnimatorSet和ObjectAnimator配合使用.ObjectAnimato ...
- Android动画:模拟开关按钮点击打开动画(属性动画之平移动画)
在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率.另外说到动画,在Android里面支持3种动画: 逐帧动画(Frame Ani ...
- android104 帧动画,补间动画,属性动画
##帧动画FrameAnimation* 多张图片快速切换,形成动画效果* 帧动画使用xml定义 package com.itheima.frameanimation; import android. ...
- Android 动画及属性动画
Android 平台提供了一套完整的动画框架,在Android3.0之前有两种动画Tween Animation(补间动画)和Frame Animation(帧动画), 对应SDK中的View Ani ...
- Android至ViewPager添加切换动画——使用属性动画
转载请注明出处:http://blog.csdn.net/allen315410/article/details/44200623 ViewPager作为Android最经常使用的的组件之中的一个.相 ...
随机推荐
- Linux基础知识整理
一.基础知识 1.Linux简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件 ...
- C# Activator.CreateInstance()方法使用
C#在类工厂中动态创建类的实例,所使用的方法为: 1. Activator.CreateInstance (Type) 2. Activator.CreateInstance (Type, Objec ...
- java实现二叉树
栈在遍历的时候不能使用for循环,因为他的size函数在动态变小.
- FPGA优化之高扇出
Fanout即扇出,模块直接调用的下级模块的个数,如果这个数值过大的话,在FPGA直接表现为net delay较大,不利于时序收敛.因此,在写代码时应尽量避免高扇出的情况.但是,在某些特殊情况下,受到 ...
- Azure的负载均衡机制
负载均衡一直是一个比较重要的议题,几乎所有的Azure案例或者场景都不可避免,鉴于经常有客户会问,所以笔者觉得有必要总结一下. Azure提供的负载均衡机制,按照功能,可以分为三种:Azure Loa ...
- python中不同包之间调用方法、
在pycharm中... 当两个py文件在同一个文件夹下的时候.直接from 文件名 import * 即可 当两个文件在不同的文件夹下的时候.需要在文件中加入 _init_.py 文件.里面可以什 ...
- mac php环境启动
mac 环境下,用brew安装php相关环境启动命令 说明 这里php,mysql,nginx都是用brew安装,安装目录默认,在Cellar下面 php-fpm 带配置重启 /*注意权限,加 sud ...
- jsonp 实例
一直以为很复杂吧?其实很简单,简单到你不敢相信 1.前端引好jquery文件 2.前端代码: $.ajax({ url: 'http://www.xxxxxxxx.com/expand.a ...
- sublime text快捷键
Ctrl+Shift+V:粘贴并格式化Ctrl+D:选择单词,重复可增加选择下一个相同的单词Ctrl+L:选择行,重复可依次增加选择下一行Ctrl+M:跳转到对应括号Ctrl+K+B:开关侧栏Ctrl ...
- echarts饼图
1.添加点击事件并跳转到不同的页面 // 路径配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist/' ...