当前位置:首页 » 安卓系统 » android动画实例

android动画实例

发布时间: 2023-03-24 05:32:35

A. Android开发之ImageView播放GIF动画实例

Android开发之ImageView播放GIF动画实例

Android的原生控件并不支持播放GIF格式的图片,如果想在Android中显示一张GIF动态图片,可以利用 ImageView控件来完成,但是放进去之后,你会发现,ImageView它只会显示这张图片的第一帧,不会产生任何的动画效果。我们必须通过自定义控件的方式来实现ImageView播放GIF 图片的功能。

首先我们来编写一个PowerImageView控件,让它既能支持ImageView控件原生的所有功能,同时还可以播放GIF动态图片。

先新建一个项目PowerImageViewTest,这里使用Android 4.0+Eclipse。

由于是要自定义控件,会需要一些自定义的控件属性,因此我们需要在values目录下新建一个attrs.xml的文件,在这个文件中添加项目需要的自定义属性。

这里我们目前暂时只需要一个自动播放auto_play属性,XML文件代码如下:

<?xml version="1.0" encoding="utf-8"?>

这个文件完成之后,下面我们来开始编写主类PowerImageView类,由于PowerImageView类需要支持ImageView的所有功能,我们必须要让PowerImageView继承自ImageView,代码如下:

public class PowerImageView extends ImageView implements OnClickListener {

/**

* 播放GIF动画的关键类

*/

private Movie mMovie;

/**

* 开始播放按钮图片

*/

private Bitmap mStartButton;

/**

* 记录动画开始的时间

*/

private long mMovieStart;

/**

* GIF图片的宽度

*/

private int mImageWidth;

/**

* GIF图片的高度

*/

private int mImageHeight;

/**

* 图片是否正在播放

*/

private boolean isPlaying;

/**

* 是否允许自动播放

*/

private boolean isAutoPlay;

/**

* PowerImageView构造函数。

*

* @param context

*/

public PowerImageView(Context context) {

super(context);

}

/**

* PowerImageView构造函数。

*

* @param context

*/

public PowerImageView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

/**

* PowerImageView构造函数,在这里完成所有必要的初始化操作。

*

* @param context

*/

public PowerImageView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PowerImageView);

int resourceId = getResourceId(a, context, attrs);

if (resourceId != 0) {

// 当资源id不等于0时,就去获取该资源的流

InputStream is = getResources().openRawResource(resourceId);

// 使用Movie类对流进行解码

mMovie = Movie.decodeStream(is);

if (mMovie != null) {

// 如果返回值不等于null,就说明这是一个GIF图片,下面获取是否自动播放的属性

isAutoPlay = a.getBoolean(R.styleable.PowerImageView_auto_play, false);

Bitmap bitmap = BitmapFactory.decodeStream(is);

mImageWidth = bitmap.getWidth();

mImageHeight = bitmap.getHeight();

bitmap.recycle();

if (!isAutoPlay) {

// 当不允许自动播放的时候,得到开始播放按钮的图片,并注册点击事件

mStartButton = BitmapFactory.decodeResource(getResources(),R.drawable.start_play);

setOnClickListener(this);

}

}

}

}


@Override

public void onClick(View v) {

if (v.getId() == getId()) {

// 当用户点击图片时,开始播放GIF动画

isPlaying = true;

invalidate();

}

}


@Override

protected void onDraw(Canvas canvas) {

if (mMovie == null) {

// mMovie等于null,说明是张普通的图片,则直接调用父类的onDraw()方法

super.onDraw(canvas);

} else {

// mMovie不等于null,说明是张GIF图片

if (isAutoPlay) {

// 如果允许自动播放,就调用playMovie()方法播放GIF动画

playMovie(canvas);

invalidate();

} else {

// 不允许自动播放时,判断当前图片是否正在播放

if (isPlaying) {

// 正在播放就继续调用playMovie()方法,一直到动画播放结束为止

if (playMovie(canvas)) {

isPlaying = false;

}

invalidate();

} else {

// 还没开始播放就只绘制GIF图片的第一帧,并绘制一个开始按钮

mMovie.setTime(0);

mMovie.draw(canvas, 0, 0);

int offsetW = (mImageWidth - mStartButton.getWidth()) / 2;

int offsetH = (mImageHeight - mStartButton.getHeight()) / 2;

canvas.drawBitmap(mStartButton, offsetW, offsetH, null);

}

}

}

}


@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if (mMovie != null) {

// 如果是GIF图片则重写设定PowerImageView的大小

setMeasuredDimension(mImageWidth, mImageHeight);

}

}


/**

* 开始播放GIF动画,播放完成返回true,未完成返回false。

*

* @param canvas

* @return 播放完成返回true,未完成返回false。

*/

private boolean playMovie(Canvas canvas) {

long now = SystemClock.uptimeMillis();

if (mMovieStart == 0) {

mMovieStart = now;

}

int ration = mMovie.ration();

if (ration == 0) {

ration = 1000;

}

int relTime = (int) ((now - mMovieStart) % ration);

mMovie.setTime(relTime);

mMovie.draw(canvas, 0, 0);

if ((now - mMovieStart) >= ration) {

mMovieStart = 0;

return true;

}

return false;

}


/**

* 通过java反射,获取到src指定图片资源所对应的id。

*

* @param a

* @param context

* @param attrs

* @return 返回布局文件中指定图片资源所对应的id,没有指定任何图片资源就返回0。

*/

private int getResourceId(TypedArray a, Context context, AttributeSet attrs) {

try {

Field field = TypedArray.class.getDeclaredField("mValue");

field.setAccessible(true);

TypedValue typedValueObject = (TypedValue) field.get(a);

return typedValueObject.resourceId;

} catch (Exception e) {

e.printStackTrace();

} finally {

if (a != null) {

a.recycle();

}

}

return 0;

}


}

这个类的代码注释已经非常详细了,我再来简单地解释一下。可以看到,我们重写了ImageView中所有的构建函数,使得 PowerImageView的用法可以和ImageView完全相同。在构造函数中,则是对所有必要的数据进行了初始化操作。首先,我们调用了 getResourceId()方法去获取图片资源对应的id值,在getResourceId()方法内部是通过Java的反射机制来进行获取的。得到了图片资源的id后,我们将它转换成InputStream,然后传入到Movie.decodeStream()方法中以解码出Movie对象。如果得到的Movie对象等于null,说明这是一张普通的图片资源,就不再进行任何特殊处理,因为父类ImageView都帮我们处理好了。如果得到的 Movie对象不等于null,则说明这是一张GIF图片,接着就要去获取是否允许自动播放、图片的宽高等属性的值。如果不允许自动播放,还要给播放按钮 注册点击事件,默认是不允许自动播放的。

接下来会进入到onMeasure()方法中。在这个方法中我们进行判断,如果这是一张GIF图片,则需要将PowerImageView的宽高重定义,使得控件的大小刚好可以放得下这张GIF图片。

再往后就会进入到onDraw()方法中。在这个方法里同样先判断当前是一张普通的图片还是GIF图片,如果是普通的图片就直接调用 super.onDraw()方法交给ImageView去处理就好了。如果是GIF图片,则先判断该图是否允许自动播放,允许的话就调用 playMovie()方法去播放GIF图片就好,不允许的话则会先在PowerImageView中绘制该GIF图片的第一帧,并在图片上绘制一个播放 按钮,当用户点击了播放按钮时,再去调用playMovie()方法去播放GIF图片。

下面我们来看看playMovie()方法中是怎样播放GIF图片的吧。可以看到,首先会对动画开始的时间做下记录,然后对动画持续的时间做下记 录,接着使用当前的时间减去动画开始的时间,得到的时间就是此时PowerImageView应该显示的那一帧,然后借助Movie对象将这一帧绘制到屏 幕上即可。之后每次调用playMovie()方法都会绘制一帧图片,连贯起来也就形成了GIF动画。注意,这个方法是有返回值的,如果当前时间减去动画 开始时间大于了动画持续时间,那就说明动画播放完成了,返回true,否则返回false。

完成了PowerImageView的编写,下面我们就来看一看如何使用它吧,其实非常简单,打开或新建activity_main.xml,代码如下所示:

<relativelayout p=""

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/anim"

/>


可以看到,PowerImageView的用法和ImageView几乎完全一样,使用android:src属性来指定一张图片即可,这里指定的anim就是一张GIF图片。然后我们让PowerImageView在布局里居中显示MainActivity中的代码都是自动生成的,这里就不再贴出来了。在AndroidManifest.xml中还有一点需要注意,有些4.0 以上系统的手机启动了硬件加速功能之后会导致GIF动画播放不出来,因此我们需要在AndroidManifest.xml中去禁用硬件加速功能,可以通过指定android:hardwareAccelerated属性来完成,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>

<manifest p=""

package="com.example.powerimageviewtest"

android:versionCode="1"

android:versionName="1.0" >


<uses-sdk p=""

android:minSdkVersion="14"

android:targetSdkVersion="17" />


android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme"

android:hardwareAccelerated="false"

>

android:name="com.example.powerimageviewtest.MainActivity"

android:label="@string/app_name" >


现在可以来运行一下代码了,一打开程序你就会看到GIF图片的第一帧,点击图片之后就可以播放GIF动画了。

然后我们还可以通过修改activity_main.xml中的代码,给它加上允许自动播放的属性,代码如下所示:

<relativelayout p=""

xmlns:attr="http://schemas.android.com/apk/res/com.example.powerimageviewtest"

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/anim"

attr:auto_play="true"

/>


这里使用了刚才我们自定义的属性,通过attr:auto_play来启用和禁用自动播放功能。现在将auto_play属性指定成true后,PowerImageView上就不会再显示一个播放按钮,而是会循环地自动播放动画。不仅如此,PowerImageView还继承了ImageView原生的所有功能,只要指定的不是GIF图 片,PowerImageView表现的结果就和ImageView完全一致,现在我们来放一张普通的PNG图片,修改 activity_main.xml中的代码,如下所示:

<relativelayout p=""

android:layout_width="match_parent"

android:layout_height="match_parent" >


<com.example.powerimageviewtest.powerimageview p=""

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:src="@drawable/myphoto"

/>


这里在src属性里面指定了一张名字为myphoto的PNG图片,图片在布局正中央显示出来了,正是普通ImageView所具备的功能。我们还可以在PowerImageView中指定android:scaleType等属性,用法和原生的ImageView完全一样。

B. Carson带你学Android:常见的三种动画类型

Android 动画主要分为分为两大类(三种):

下面。我将简单介绍这两大类、三种 Android 常用动画

根据不同的动画效果,补间动画分为4种动画:

具体效果分别如下:

较为复杂的个性化动画效果。

将动画拆分后的图片帧

在 Android 3.0 ( API 11 )后才提供的一种全新动画模式

与属性相关、更加复杂的动画效果。

不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度

C. Android动画一:Activity过渡动画详细实现原理

虽然 Android 5.0 之后推出了新的过渡动画方式,但通常只是用于特定的场合使用, activity.overridePendingTransition() 通用方式的过渡动画还是很常用。

overridePendingTransition有两个参数,第一个参数(enterAnim)是作用于SecondActivity 的 进入屏幕可见区域 效果,第二个参数(exitAnim)是作用于当前 Activity 离开屏幕可见区域 效果。

iOS 默认的效果,新的Activity从右边(R)数芦进入显示区域,当前Activity从左边离开显示区域到(L)。

enterAnim(activity_right_to_left_enter.xml):X轴从 100% 到 0

exitAnim(activity_right_to_left_exit.xml):X轴从 0 到 -100%

使用

一般从底部弹出新Activity,就是从B区域到屏幕可薯悔带见区域,当前的Activity是保持不变的。
enterAnim(activity_bottom_to_top_enter.xml):Y轴从 100% 到 0

exitAnim(no_anim.xml):Y轴保持不变

使用

前面讲了startActivity的转场动画,下面讲finish()的转场动画。overridePendingTransition有两个参数,第一个参数(enterAnim)是作用于上一个Activity的进入屏幕可见区域效果,第二个参数(exitAnim)是作用于当前哗前 Activity 离开屏幕可见区域效果。

iOS默认的finish动画,是当前的Activity从屏幕可见区域到R区域,上一个Activity从L区域到屏幕可见区域。

enterAnim(activity_left_to_right_enter.xml):X轴从 -100% 到 0

exitAnim(activity_left_to_right_exit.xml):X轴从 0 到 100%

使用

从屏幕底部滑出效果是,当前Activity从底部滑出屏幕可见区域,上一个Activity保持不变,和BottomIn不同的是,enterAnim是不需要使用动画,因为上一个Activity已经在屏幕的后面了,只需要改变当前Activity消失的效果。
exitAnim(activity_top_to_bottom_exit.xml):Y轴从 0 到 100%

使用

https://github.com/taoweiji/ActivityAnimationExample

D. Android 动画详解

  android中酷炫的效果,都离不开动画的支持。这里我们详细介绍一下android中动画的分类。android的中动画分为帧动画、补间动画、属性动画。原理各不相同,实现的效果也大不相同。下面一一讲解三种动画。

  帧动画顾名思义就是通过顺序一帧一帧播放图片从而产生动画效果,效果类似放电影。该动画缺点比较明显,就是如果图片过大过多会导致OOM。帧动画xml文件放置在drawable目录下而非anim文件夹下。

  补间动画是通过对view进行旋转、缩放、渐变、透明度变化,而达到的一种动画效果。是一种渐进式动画。并且可以通过组合以上四种操作,完成复杂的自定义动画效果。缺点就是只是改变的view的展示状态,但是不会改变view的位置。例如我们将一个button通过位移想左移动100dp,然后停留在终点。但是我们可以发现展示的位置button点击无效果,不可以交互。而在button原始位置空白的地方点击会触发button的点击效果。也就是button本质还是在原来位置,只是展示左移了100dp。

透明度动画,通过改变view的透明度展示动画。对应AlphaAnimation和<alpha>xml标签

缩放动画,通过修改view的大小展示动画。对应ScaleAnimation类和<scale>xml表情

通过旋转view展示动画。对应RotateAnimation类和<rotate>xml标签

平移动画,更改view的展示位置展示动画。对应TranslateAnimation类和<translate>xml表情

应用动画xml配置

使用java类配置动画,具体参数类同xml参数,建议使用xml配置动画

  属性动画本质是通过改变对象的属性(例如:x,y等属性),来实现动画的,所以基本上是无所不能的,只要对象有这个属性,就能实现动画效果。属性动画是在api11的新特性,通过动态的改变view的属性从而达到动画效果。虽然可以使用nineoldandroid库向下兼容,但是兼容本质是使用补间动画完成,也就是说不会更改view的属性,也不会更改view的位置。属性动画比较常用的类: ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子类,而AnminationSet是动画集合

动画配置同样可以使用xml配置,参数类似,这里不做详细说明。

根据时间流逝百分比计算当前属性改变百分比。同xml配置动画中的 android:interpolator 属性配置,常见有LinearInterpolator(线性差值器)、(加速减速差值器)
等。自定义需要实现 Interpolator 或者 TimeInterpolator 。Interpolator接口继承TimeInterpolator。

根据当前属性改变百分比计算改变后的属性值。属性动画特有的属性。自定义估值器需要实现 TypeEvaluator 接口。

可以对任意属性做属性动画,属性动画要求动画作用的对象提供该属性的get()和set()方法。因为属性动画本质就是根据外界传递的对象属性的初始值和终点值,然后根据估值器和差值器计算属性值,不断调用属性的set方法,通过时间的推移所传递的值,越来越近终点值。
注意:

使用ValueAnimator通过监听动画过程,自己改变对象属性完成动画

E. 【Android 动画】动画详解之补间动画(一)

之前很早就想写写Android 的动画,最近刚好有时间,大概聊一聊安卓动画。

个人习惯将动画分为:补间动画(透明度、旋转、位移、缩放)、帧动画、和属性动画,这一篇,我们先说说补间动画。
补间动画这个词出于flash,在两个关键帧( 可以理解成动画开始和结束 )中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。
实际上,Android 的补间动画也是由我们指定动画开始、动画结束2个关键点,中间部分的动画由系统完成

在正式开始之前,我们先说下Android 系统的坐标系,屏幕左上角为坐标原点,假如屏幕为1080*1980,那么左上角为(0,0),右上角为(1080,0),左下角为(0,1980),右下角为(1080,1980)

所有动画有以下公共属性,注释比较详细,这里就不在详述了

ScaleAnimation有3种构造方法

我们先看第一种,其起始比例为0,缩放比例为1.4,即放大到1.4倍

效果如下:

第二种,pivotx,pivotY分别代表起始位置的x、y方向的坐标,我们设置为(100,100)

效果如下:

第三种,pivotXType和pivotYType有2种模式,RELATIVE_TO_SELF(相对于自身)和RELATIVE_TO_PARENT(相对于父布局),如果设置这个,pivotx,pivotY的值就应该是0-1的浮点数,这里分别对应xml中的%(自身)和%p(父布局)

TranslateAnimation有2种构造方法,和ScaleAnimation类似

效果如下:

效果如下:

RELATIVE_TO_PARENT

效果如下:

RotateAnimation有3种构造方法

顺时针720度

效果如下:

逆时针720度

效果如下:

效果如下:

再来RELATIVE_TO_PARENT

效果如下:

这是什么鬼???怎么跑到屏幕外面去了?
原来设置为RELATIVE_TO_PARENT时,旋转中心x方向应该为该空间离左边的边距+父布局宽度/2,y方向同理,而此时,我们布局中红色的Textview为居中状态,所以旋转中心为屏幕右下角。让我们来看个例子
修改布局如下:

效果如下:

这时,我们看到旋转中心x方向为离左边100dp处

AlphaAnimation只有1种构造方法

其中fromAlpha为动画开始的透明度;toAlpha为动画结束的透明度

效果如下:

效果如下:

AnimationSet是一个动画的集合,可以按照添加的顺序播放动画,让我们来看个例子,通过组合动画,实现旋转渐入动画

效果如下:

到这里,补间动画就介绍完了

参考资料: 自定义控件三部曲之动画篇

F. Android播放Spine骨骼动画笔记

官方实例: http://zh.esotericsoftware.com/spine-demos
官方工具: EsotericSoftware / spine-runtimes
java相关包: https://github.com/EsotericSoftware/spine-runtimes/tree/3.8/spine-libgdx

Libgdx实现和原生view进行层级透明叠加,修改GLSurfaceView为GLTextureview:
https://www.pianshen.com/article/6271275180/
此篇文章CSDN地址

检查了我们的json文件中的name,没有为null值的啊,于是对比可以运行的spine文件json发现:

最后发现是果然还是我的libgdx太搭并老,升级为最新的运枝握即旁庆可

之前的版本是

注意:升级成为新版本,那么格式也要用新版本,就是那种缺省了字段的json格式
所以版本匹配很重要。

而Demo只有 'armeabi','armeabi-v7a', 'x86' 这三个so的支持,于是我们修改配置如下

于是就可以正确的运行了,如果想支持其他的cup架构,那么就要找到对应的架构的 libgdx.so 文件,添加到项目中。

更新后:

这是1.9.10的介绍: https://www.badlogicgames.com/wordpress/

G. android属性动画详解

在 Android 动画中,总共有两种类型的动画View Animation(视图动画)和Property Animator(属性动画);其中
View Animation包括Tween Animation(补间动画)和Frame Animation(逐帧动画);
Property Animator包括ValueAnimator和ObjectAnimation;
首先,直观上,他们有如下三点不同:
1、引入时间不同: View Animation是API Level 1就引入的。Property Animation是API Level 11引入的,即Android 3.0才开始有Property Animation相关的API。
2、所在包名不同: View Animation在包android.view.animation中。而Property Animation API在包 android.animation中。
3、动画类的命名不同: View Animation中动画类取名都叫XXXXAnimation,而在Property Animator中动画类的取名则叫XXXXAnimator大家都知道逐帧动画主要是用来实现动画的,而补间动画才能实现控件的渐入渐出、移动、旋转和缩放的;而Property Animator是在Android 3.0版本才引入的,之前是没有的。
为什么还要引入Property Animator呢?
1、为什么引入Property Animator(属性动画)
我提出一个假设:请问大家,如何利用补间动画来将一个控件的背景色在一分钟内从绿色变为红色?这个效果想必没办法仅仅通过改变控件的渐入渐出、移动、旋转和缩放来实现吧,而这个效果是可以通过Property Animator完美实现的
**这就是第一个原因:Property Animator能实现补间动画无法实现的功能 **大家都知道,补间动画和逐帧动画统称为View Animation,也就是说这两个动画只能对派生自View的控件实例起作用;而Property Animator则不同,从名字中可以看出属性动画,应该是作用于控件属性的!正因为属性动画能够只针对控件的某一个属性来做动画,所以也就造就了他能单独改变控件的某一个属性的值!比如颜色!这就是Property Animator能实现补间动画无法实现的功能的最重要原因。
**我们得到了第二点不同:View Animation仅能对指定的控件做动画,而Property Animator是通过改变控件某一属性值来做动画的。
**假设我们将一个按钮从左上角利用补间动画将其移动到右下角,在移动过程中和移动后,这个按钮都是不会响应点击事件的。这是为什么呢?因为补间动画仅仅转变的是控件的显示位置而已,并没有改变控件本身的值。View Animation的动画实现是通过其Parent View实现的,在View被drawn时Parents View改变它的绘制参数,这样虽然View的大小或旋转角度等改变了,但View的实际属性没变,所以有效区域还是应用动画之前的区域;我们看到的效果仅仅是系统作用在按钮上的显示效果,利用动画把按钮从原来的位置移到了右下角,但按钮内部的任何值是没有变化的,所以按钮所捕捉的点击区域仍是原来的点击区域。(下面会举例来说明这个问题)
这就得到了第三点不同:补间动画虽能对控件做动画,但并没有改变控件内部的属性值。而Property Animator则是恰恰相反,Property Animator是通过改变控件内部的属性值来达到动画效果的

我们前面讲了Property Animator包括ValueAnimator和ObjectAnimator;这篇文章就主要来看看ValueAnimator的使用方法吧。
我觉得谷歌那帮老头是最会起名字的人,单从命名上,就能看出来这个东东的含义。ValueAnimator从名字可以看出,这个Animation是针对值的! ValueAnimator不会对控件做任何操作,我们可以给它设定从哪个值运动到哪个值,通过监听这些值的渐变过程来自己操作控件。 它会自己计算动画的过程,然后我们需要监听它的动画过程来自己操作控件。

这就是ValueAnimator的功能:ValueAnimator对指定值区间做动画运算,我们通过对运算过程做监听来自己操作控件。
总而言之就是两点:
1. ValueAnimator只负责对指定的数字区间进行动画运算
2. 我们需要对运算过程进行监听,然后自己对控件做动画操作

插值器的意义其实就相当于物理公式中的加速度参数,所以这也就是它也叫加速器的原因。 如何自定义插值器:

**input参数与任何我们设定的值没关系,只与时间有关,随着时间的增长,动画的进度也自然的增加,input参数就代表了当前动画的进度。而返回值则表示动画的当前数值进度 **

在getInterpolation函数中,我们将进度反转过来,当传0的时候,我们让它数值进度在完成的位置,当完成的时候,我们让它在开始的位置

ObjectAnimator是派生自ValueAnimator的,所以ValueAnimator中所能使用的方法,在ObjectAnimator中都可以正常使用。ObjectAnimator重写了几个方法,比如ofInt(),ofFloat()等。利用ObjectAnimator重写的ofFloat方法如何实现一个动画:(改变透明度)

前面我们都是定义多个值,即至少两个值之间的变化,那如果我们只定义一个值呢,如下面的方式:(同样以MyPointView为例)

仅且仅当我们只给动画设置一个值时,程序才会调用属性对应的get函数来得到动画初始值。如果动画没有初始值,那么就会使用系统默认值。比如ofInt()中使用的参数类型是int类型的,而系统的Int值的默认值是0,所以动画就会从0运动到100;也就是系统虽然在找到不到属性对应的get函数时,会给出警告,但同时会用系统默认值做为动画初始值。
如果通过给自定义控件MyPointView设置了get函数,那么将会以get函数的返回值做为初始值。

根据 View setBackGroundColor() 方法可以自定义条用属性动画。

H. 如何高效学习Android动画

Android动画初步
动画(Animation)在我们日常的Android开发工作当中使用得较为频繁,尤其对于Android游戏这个动画的集合体,掌握动画开发的重要性毋庸置疑。同样的,在Android应用开发中我们也经常使用动画效果来提升APP用户体验,比如应用中的图片的旋转,页面和页面之间的淡入淡出、左右渐入渐出切换效果等等。
动画的分类
Android FrameWork向开发人员提供了丰富的API用于实现各种各样的动画效果,而若要对动画分类,一般可将Android动画分为以下两类的动画系统:
View Animation
View Animation动画系统又可以分类成Tween Animation 和Frame Animation:
Tween Animation
Tween Animation是Android系统比较老的一种动画系统,它的特点是通过对场景里的对象不断做图像变换(渐变、平移、缩放、旋转)产生动画效果,且这种动画只适用于View对象。
Frame Animation
Frame Animation也是常用到的动画,它的原理比较简单,就是将一系列准备好的图片按照顺序播放,形成动画效果。
Property Animation
Property Animation(属性动画)是在Android3.0(API 11)之后引入的一种动画系统,该动画提供了比View Animation更加丰富、强大和灵活的功能,Android官方推荐开发人员使用该动画系统来实现动画。Property Animation的特点是动态地改变对象的属性从而达到动画效果。该动画实现使用于包括View在内的任何对象。

Tween Animation
了解到Tween Animation是Android中比较老的一种动画系统,且其只能实现对View对象动画设置,不过其虽然没有Property Aniamtion功能那么强大和灵活,但是使用Tween Animation依然能完成日常大部分的开发需求。灵活地掌握Tween Animation的使用方法,十分有必要。那Tween Animation实现View的动画,一般分为以下几种效果:
Alpha:渐变透明动画效果;
Scale:渐变尺寸伸缩动画效果;
Translate:位置位移动画效果;
Rotate:位置旋转动画效果。
接下来通过实例来一一学习如何实现以上几种动画效果,实现Tween Animation分为xml实现和代码实现,下面会分别使用这两种方式来实现上面的的几种动画效果。首先使用xml方式来实现View的Alpha渐变透明动画效果,在项目目录结构中创建res/anim文件夹,然后在文件夹中创建view_animation_alpha.xml文件,文件中的代码如下:
[html] view plain


<!--
* android:interpolator:修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),
* decelerated(减速),repeated(重复),bounced(弹跳)等。
* android:fromAlpha="0.0":设置动画开始时控件的透明度,0.0为透明,控件不显示,1.0为不透明,控件全部显示
* android:toAlpha="1.0":设置动画结束时的控件的透明度
* android:ration="2500":设置每一次动画持续的时间值
* android:repeatCount="5":设置动画重复的次数
* android:repeatMode="reverse":设置动画重复的模式,reverse为0.0 -> 1.0 -> 0.0,动画反复执行;
* restart为0.0 -> 1.0, 0.0 -> 1.0,动画每次都重新开始执行
-->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:ration="2500"
android:repeatCount="5"
android:repeatMode="reverse"
/>
xml文件中的属性在代码中都有详细的解释,这里就不重复说明了。定义完XML文件后,然后在代码中使用AnimationUtils类调用loadAnimation(context, id)方法来加载xml文件,具体代码如下:
[java] view plain


/**
* xml文件加载图片渐变(Alpha)动画
*/
Animation mAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation_alpha);
上面是使用xml实现Alpha的动画效果,下面我们来看看如何在代码中实现Alpha的动画,很简单,只需要实例化一个AlphaAnimation对象,然后传递相关参数就行,具体代码如下:
[java] view plain


/**
* 代码创建图片渐变(Alpha)动画
* 实例化AlphaAnimation对象:
* mAnimation = new AlphaAnimation(fromAlpha, toAlpha);
* fromAlpha:设置动画开始时控件的透明度,0.0为透明,控件不显示,1.0为不透明,控件全部显示
* toAlpha:设置动画结束时的控件的透明度
*/

Animation mAnimation = new AlphaAnimation(0.0f, 1.0f);
分别使用xml和代码实现Alpha动画后,最后为一个ImageView对象设置创建好的Alpha动画,ImageView对象只需要调用startAnimation(Animation animation)方法,将刚刚创建好的alpha动画对象作为参数添加传进去搞定,具体代码如下:
[java] view plain


ImageView mImageView = (ImageView)findViewById(R.id.view_animation_imageview);
//设置控件开始执行动画
mImageView.startAnimation(mAnimation);

I. Android属性动画之旋转动画

CSDN同步发布

旋转动画有三种

角度增加是逆时针方向旋转。注意,如果旋转角度是90度的话,最终View会不可见。

当要旋转的View尺寸很小的时候,效果很好,但是当View很大的时候,就出问题了。如下所示:

当时很奇怪为啥会这样呢?最后是在这篇文章 实现翻转卡片的动画效果 看到了一个叫cameraDistance的东西,然后感觉可能这个有用,试了试果然可以。

View的 getCameraDistance 方法。

View的 setCameraDistance 方法,看注释。

注意:注释中的这段这个相源袭机距离用“深度像素”来表示。默认的距离依赖屏幕的密度。例如,在一个中等没裂枣密度的屏幕上,默认的距离是1280。在高密度的屏幕上,默认距离是1920。我认为这个单位是dp。1280dp,1920dp。我的测试机density是2.75,通过getCameraDistance方法,获枯拆取到的值是3520.0,3520.0除以2.75就是1280。

注意:关于设置cameraDistance,建议始终使用大于此视图高度(绕X轴旋转)或宽度(Y轴旋转)的相机距离。而且这个距离得比较大才行,我测试下来得10000以上才可以。如下所示:

同样需要设置 cameraDistance

平时这个用的比较多应该,也比较简单。也不涉及 cameraDistance 的东西。

参考链接

热点内容
如何恢复儿童储蓄密码箱原始密码 发布:2025-05-11 18:57:10 浏览:285
javajdk区别 发布:2025-05-11 18:45:21 浏览:35
如何防止apk被反编译 发布:2025-05-11 18:45:16 浏览:152
安卓什么功能好 发布:2025-05-11 18:21:31 浏览:354
我的世界2b2t服务器中国版 发布:2025-05-11 18:16:35 浏览:693
萌将风云脚本 发布:2025-05-11 18:07:14 浏览:745
密码锁aid代表什么 发布:2025-05-11 18:00:01 浏览:757
编程的组成 发布:2025-05-11 17:58:34 浏览:808
火山易语言apk反编译 发布:2025-05-11 17:52:01 浏览:814
钢琴密码锁本的密码该在哪里看 发布:2025-05-11 17:49:44 浏览:469