初识android动画(4)之属性动画
来源:互联网 发布:windows 10桌面美化 编辑:程序博客网 时间:2024/06/12 22:32
属性动画算是Android动画里面比较麻烦的一种动画了。不过就是因为它麻烦所以也能更好地满足我们的需求。属性动画是在3.0以后添加的。功能十分强大。接下来我们将重点的讲讲。如果对其他几种动画不了解的话可以先看看我的前几篇博客初识android动画。下面的内容均在前几篇的基础上讲的。我们看一下官方提供的使用属性动画制作的酷炫的例子吧!!!
先给出官方的API 点击打开链接
属性动画与传统动画的区别
当我们点击按钮的时候,一个圆由位置一转到位置二。我们也为这个圆设置一个点击事件,当点击圆的时候弹出一个Toast。我们传统的做法是什么呢?肯定是设置一个传统的TranslateAnimation属性,为其设置位置就可以了。现在我们在位置一点击圆肯定能弹出一个Toast。但是我们的位置发生变化之后,我们再去点击圆发现没有Toast了。但是我们在原来的位置一上点击发现能够Toast,怎么回事呢?这就是传统动画的弊端了。 传统动画考虑的是一个View的重新绘制。当我们执行动画的时候其实就是一个个View不断地去重新绘制。而我们的属性动画就可以很好的解决这一问题。
属性动画一:ObjectAnimator
ObjectAnimator是属性动画里面比较简单但是也是会经常用到的一个对象。他其实执行的是一个异步任务。我们再给出官方的API 点击打开链接
那么我们如何去使用呢?接着前面提到的一个例子
我们定义了一个按钮,一张图片。点击按钮启动动画;
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //图片的点击事件 public void click(View view){ Toast.makeText(MainActivity.this, "点击了图片", Toast.LENGTH_SHORT).show(); } //按钮的监听事件 public void move(View view){ ImageView imageView=(ImageView) findViewById(R.id.imageView1); ObjectAnimator animator=new ObjectAnimator(); animator.ofFloat(imageView, "translationX", 0f,200f).start(); } }
我们看到,我们用属性动画特别的简单,就是一句话,而且用属性动画,我们也很好的解决了上面的问题。当我们使用其他属性的时候,直接调用其他的就好。在这里我们使用了TranslationX.当然我们还有其他的一些属性。
如果我们使用ObjiecAnimation为ImageView同时定义多个动画会怎么样呢?答案就是同时会播放这几个动画。下面看一下还有没有其他的几种方法。
(1)同时使用ObjiecAnimator
我们将上面MainActivity中的代码修改一下
ObjectAnimator.ofFloat(imageView, "translationX", 0f,200f).setDuration(3000).start(); ObjectAnimator.ofFloat(imageView, "translationY", 0f,200f).setDuration(3000).start(); ObjectAnimator.ofFloat(imageView, "rotation", 0f,360f).setDuration(3000).start();(2)同时使用PropertyVlaueHolder:
使用这种属性的好处就是他的性能好, 节省系统资源
PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("translationX",0f,200f); PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("translationY", 0f,200f); PropertyValuesHolder p3=PropertyValuesHolder.ofFloat("rotation", 0f,360f); ObjectAnimator.ofPropertyValuesHolder(imageView, p1,p2,p3).setDuration(3000).start();(3)使用AnimatorSet
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageView, "translationX", 0f,200f).setDuration(3000); ObjectAnimator animator2=ObjectAnimator.ofFloat(imageView, "translationY", 0f,200f).setDuration(3000); ObjectAnimator animator3=ObjectAnimator.ofFloat(imageView, "rotation", 0f,360f).setDuration(3000); AnimatorSet set=new AnimatorSet(); set.playTogether(animator1,animator2,animator3); set.start();我们使用以上的三种方法都可以实现同时播放我们的好几种动画。其中AnimatorSet功能最为强大。不仅仅可以同时播放好几种动画,还可以控制动画的播放顺序
//按照顺序依次播放 set.playSequentially(animator1,animator2,animator3); //动画2和动画3同时播放,动画一在他们之后播放 set.play(animator2).with(animator3); set.play(animator1).after(animator2);
属性动画二:监听事件
有时候我们在动画播放的过程中,或者前后会引发一系列事件,这时候我们就可以添加
ObjectAnimator animator1=ObjectAnimator.ofFloat(imageView, "translationX", 0f,200f).setDuration(3000); //添加监听事件 animator1.addListener(new AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationCancel(Animator animation) {// TODO Auto-generated method stub}}); //有选择的添加监听事件 animator1.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // TODO Auto-generated method stub super.onAnimationEnd(animation); }});代码很简单一眼就能明白。
属性动画三: ValueAnimator数值发生器
什么是ValueAnimator呢?
前面我们提到ObjectAnimator可以定义一个动画到View的某一个属性。其实ObjectAnimator就是继承了ValueAnimator。 而ValueAnimator则不会产生这样一种效果。它的本质就是一个数值发生器。他可以产生你想要的各种数值。他可以计算属性动画中每一步的具体动画效果。ValueAnimator会根据动画已进行的时间与其持续的总时间的比值产生一个0~1的时间因子,有了这样一个时间因子,经过相应的变换,就可以根据startValue()和endValue()来生产中间的相应值。同时,通过插值器的使用,可以进一步地控制每一个时间因子产生值的变化速率。下面看一看该如何用?这里使用一个数值计算器。
我们要实现的效果是什么呢,就是在点击一个按钮之后,按钮的显示内容会从0-10不断地递增。如果按照以前的做法,我们肯定是在线程中定义一个for循环,每一段时间更新一个数值。其实呀,这种方法是非常的耗费系统资源的。ValueAnimator也可以实现这样的一种效果。
下面是实现的代码
public class MyActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.my_activity);super.onCreate(savedInstanceState);}public void click(View view){//获得Button对象final Button button=(Button)findViewById(R.id.my_button);//新建一个ValueAnimator,让其中的数值从0-10ValueAnimator animator=ValueAnimator.ofInt(0,10);//从0-10在10秒内变化animator.setDuration(10000);//为其添加事件animator.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {//获得ValueAnimator的植Integer value=(Integer) animation.getAnimatedValue();button.setText(""+value);}});animator.start();//启动动画}}我们看到没有使用线程。也可以实现。现在大家应该能够自然而言的想到一些其他的一些应用场景了吧。例如在0-3之间我们产生一个时间,3-7之间做另外一件事等等。上面我们直接使用的ofInt。这是谷歌给我定义好的一种模式。那我们能不能自己定义一些数值计算器呢?答案是肯定的。
//自定义数值计算器ValueAnimator animator=ValueAnimator.ofObject(new TypeEvaluator<PointF>() {//通过evaluate返回各种各样的植,我们拿到这些值之后就可以为所欲为了。@Overridepublic PointF evaluate(float arg0, PointF arg1, PointF arg2) {// TODO Auto-generated method stubreturn null;}});fraction: :时间因子,从0-1之间变化 arg1 :开始值 arg2 :结束值
我们自定义这些值可以应用到插值器中:定义自己的插值器。如果对插值其不了解的话。看我的另外一篇博客
初始android动画
下面给一张插值器的数值变化表,
总结:
下面总结了一下属性动画中常用的一些方法类和接口。
接下来根据前面学的知识,做一个小的案例。先看一下效果:
先在我们res/drawable/文件中添加一些列图片。然后在布局文件中声明:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageView_h" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/h" /> <ImageView android:id="@+id/imageView_g" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/g" /> <ImageView android:id="@+id/imageView_f" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/f" /> <ImageView android:id="@+id/imageView_e" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/e" /> <ImageView android:id="@+id/imageView_d" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/d" /> <ImageView android:id="@+id/imageView_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/c" /> <ImageView android:id="@+id/imageView_b" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/b" /> <ImageView android:id="@+id/imageView_a" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/a" /> </FrameLayout>然后在我们activity中运用就可以了。
public class MainActivity1 extends Activity implements OnClickListener {//定义一些图片资源private int[] res = { R.id.imageView_a, R.id.imageView_b, R.id.imageView_c,R.id.imageView_d, R.id.imageView_e, R.id.imageView_f, R.id.imageView_g, R.id.imageView_h };//保存图片private List<ImageView> imageViewList = new ArrayList<ImageView>();//用于控制图片伸缩开关private boolean flag=true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//将图片添加进来for (int i = 0; i < res.length; i++) {ImageView imageView = (ImageView) findViewById(res[i]);imageView.setOnClickListener(this);imageViewList.add(imageView);}}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.imageView_a:if(flag){startAnim();}else{stopAnim();}break;}}//停止播放动画@SuppressLint("NewApi")private void stopAnim() {for (int i = 0; i < res.length; i++) {ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", i * 100, 0f);animator.setInterpolator(new BounceInterpolator());//插值器animator.setDuration(1000);animator.setStartDelay(i * 500);animator.start();flag=true;}}//开始播放动画@SuppressLint("NewApi")private void startAnim() {for (int i = 1; i < res.length; i++) {ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0f, i * 100);AnimatorSet mset=new AnimatorSet();mset.playTogether(animator);mset.setDuration(1000);mset.setStartDelay(i*500);mset.setInterpolator(new BounceInterpolator());//插值器mset.start();flag=false;}}}如果看懂了源码之后你也可以自己修改制作各种不同的效果。
点击下载源码:点击下载
1 0
- 初识android动画(4)之属性动画
- Android动画效果之初识Property Animation(属性动画)
- Android动画效果之初识Property Animation(属性动画)
- Android动画效果之初识Property Animation(属性动画)
- android 属性动画初识(-)
- Android Study 之 属性动画初识
- 笔记之android动画 初识ValueAnimator 属性动画
- android 属性动画初识(二)
- android 属性动画初识(三)
- Android动画之属性动画(二)
- Android动画之属性动画(上)
- Android动画之属性动画(下)
- Android动画之属性动画(四)
- Android 动画之属性动画
- Android动画之属性动画
- Android动画之属性动画
- android 动画 之 属性动画
- Android动画之---属性动画
- The environment variable JAVA_HOME does not point to a valid JVM installation
- 将两个有序的单向链表整合成一个有序单向链表
- 消息队列-RabbitMq(PHP)
- Problem-1042 N!
- Shell脚本编程(二)
- 初识android动画(4)之属性动画
- Theano教程:使用逻辑回归分类MNIST数字
- storm从kafka中读数据
- Qt - Button
- ThinkPad点击文件夹有声音解决方案
- 欧拉回路输出
- Java程序员从笨鸟到菜鸟之(八十四)深入浅出Ajax
- Atitit 软件开发中 瓦哈比派的核心含义以及修行方法以及对我们生活与工作中的指导意义
- 剑指offer——面试题49:不使用atoi库函数实现把字符串转换成整数