Android中动画之三属性动画高级用法一
一.目的
1.差值器和估值器的概念和介绍
2.ObjectAnimator和ValueAnimator对任意类的任意属性做动画的基本用法
二.差值器和估值器简介
目的:
为下面做准备,弄清概念很重要。
TimeInterpolator :
差值器,根据时间流逝的百分比来计算当前属性改变的百分比;同时他是最顶层的差值器接口。他下面的子类一次是Interpolator接口,BaseInterpolator抽象类,LinearInterpolator等系统带的几个差值器实现类。
TypeEvaluator:
根据当前属性改变的百分比(TimeInterpolator 中计算而来)来计算改变后的属性值。
2.1差值器
使用:
动画类ValueAnimator有public void setInterpolator(TimeInterpolator value)
方法,TimeInterpolator :差值器的最顶层接口;不调用此方法则默认使用AccelerateDecelerateInterpolator差值器。
介绍
系统自带有:LinearInterpolator(匀速),AccelerateInterpolator(加速),AccelerateDecelerateInterpolator(先加后减速),DecelerateInterpolator(减速)等几个差值器。
自定义插值器
实现Interpolator接口或者TimeInterpolator只要重写public float getInterpolation(float input)方法。
2.2估值器
使用
动画类ValueAnimator有public void setEvaluator(TypeEvaluator value)
方法,TypeEvaluator :估值器的最顶层接口;
介绍:
系统自带有:IntEvaluator(int数值估值器),IntArrayEvaluator(int数组估值器),FloatEvaluator(float估值器),FloatArrayEvaluator(float数组估值器),ArgbEvaluator(argb颜色估值器),RectEvaluator(rect矩形估值器)等实现了TypeEvaluator 接口的实现类。
自定义估值器
实现TypeEvaluator接口重写一个evaluate方法就好了。
三.对任意类的任意属性做动画—–基础
解释:
之所以称为基础,一是因为对已有类做处理,只是不能对现有属性直接使用属性动画;二是使用的是ofInt,ofFloat等使用数值的方法(这样就可以使用系统的估值器了);
注意
对任意类(Object)的任意属性(abc)做动画,想要成功要具备俩个条件:
1.Object必须提供setAbc方法;如果动画的时候没有传递初始化值,那么还要有getAbc方法,因为系统要去取abc属性的初始值(如果不满足这个条件,直接crash);
2.Object的setAbc对属性abc所做的改变必须通过某种方法表现出来,最常见的就是UI的变化。(如果不满足这个条件,不会crash,但是没有效果)
3.1例子
目的:想对现有的View(LinearLayout)的宽度属性进行动画处理
问题:
但是我们发现在直接使用ObjectAnimator ani = ObjectAnimator.ofInt(showLl,"width",100,500);
(showLl是LinearLayout)这种写法会报错,我们发现里面没有setWidth方法。同时我们发现VIew中有getWidth方法,且是我们想要的。其他View的子类这里不一一列举,大家可以举一反三。
解决方案:对于这种情况有两种可行的方案:
- 用一个类来包装原有类,间接为其提供set和get方法(建议使用这种方法,简单可靠)
- 使用ValueAnimator,监听动画过程,自己实现具体的属性的改变
3.1.1使用方案一
用一个类来包装原有类,间接为其提供set和get方法(建议使用这种方法,简单可靠)
先看效果
代码
Activity,点击执行动画操作
public class PropertyActivity extends AppCompatActivity {
private Button playBtn;
private LinearLayout showLl;
private TextView showTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
playBtn = (Button) findViewById(R.id.play_btn);
showLl = (LinearLayout) findViewById(R.id.show_ll);
showTv = (TextView) findViewById(R.id.show_tv);
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
performAni();
}
});
}
private void performAni() {
ViewWrapper viewWrapper = new ViewWrapper(showLl);
int currentWidth = viewWrapper.getWidth();
ObjectAnimator ani = ObjectAnimator.ofInt(viewWrapper,"width",currentWidth,200);
ani.setDuration(4000);
ani.start();
}
//View包装类,重要的是get,set的width方法
private static class ViewWrapper{
private View taget;
public ViewWrapper(View taget){
this.taget = taget;
}
public int getWidth(){
return taget.getWidth();
}
public void setWidth(int width){
taget.getLayoutParams().width = width;
taget.requestLayout();
}
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/play_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="play"/>
<LinearLayout
android:id="@+id/show_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#ff0000">
<TextView
android:id="@+id/show_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ff00"
android:textSize="30sp"
android:text="ProvertyAnimator"/>
</LinearLayout>
</RelativeLayout>
我们对LinearLayout的宽度属性做了动画处理,从中我们也可以想到对其他属性进行动画处理也是相同的道理,只是更改ViewWrapper的属性的get和set方法而已,关键是两个方法中具体属性的处理。
3.1.2使用方案二
使用ValueAnimator,监听动画过程,自己实现具体的属性的改变
效果图
和3.1.1中是一模一样的,这里不重复粘贴了。
关键是Activity中代码,而布局文件和3.1.1中也是一样的,这里不贴了。
注意里面的注释是关键点。
public class PropertyActivity extends AppCompatActivity {
private Button playBtn;
private LinearLayout showLl;
private TextView showTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
playBtn = (Button) findViewById(R.id.play_btn);
showLl = (LinearLayout) findViewById(R.id.show_ll);
showTv = (TextView) findViewById(R.id.show_tv);
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
performAni();
}
});
}
//下面是关键点
private void performAni() {
//获取初始宽度
final int currentWidth = showLl.getWidth();
//构造ValueAnimator,从1到100的int动画(这里的1和100可以随意得去取值不一定这俩值)
final ValueAnimator ani = ValueAnimator.ofInt(1,100);
//添加监听
ani.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//使用系统自带的估值器IntEvaluator
IntEvaluator intEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//currentValue是ValueAnimator的1到100中的某个值
int currentValue = (int) animation.getAnimatedValue();
Log.e("currentValue",currentValue+"");
//关键点:获取差值器计算所得值(进度百分比0到1)
float f = animation.getAnimatedFraction();
//利用intEvaluator来进行估值操作
showLl.getLayoutParams().width = intEvaluator.evaluate(f,currentWidth,200);
showLl.requestLayout();
}
});
ani.setDuration(4000).start();
}
}
上一篇: Android属性动画的使用(上)
下一篇: Apache Hive View
推荐阅读
-
CSS3中Transition动画属性用法详解
-
CSS3中Animation动画属性用法详解
-
Android中实现一个简单的逐帧动画(附代码下载)
-
Android开发中属性动画(ObjectAnimator)中 插值器(Time Interpolator )详解
-
从一个新的角度开始学习Android属性动画
-
Android中实现一个简单的逐帧动画(附代码下载)
-
Android 属性动画 满足一般项目中的需求
-
关于CSS3中Animation动画属性的用法解析
-
Android属性动画Property Animation系列一之ObjectAnimator_html/css_WEB-ITnose
-
Android中动画之五属性动画高级用法三