经常看一些大神的博客,大多数大神开篇都轻谈一些国内比较专注的事和一些身边琐事,以表自己心情感悟。像我这种菜鸡就直接步入正题吧。毕竟这东西就这么简单。
Android动画效果有位移、缩放。旋转。透明度等。Animation和Animator都都能实现动画效果。下面就和说下这2个不同之处吧
1、传统动画:Animaton系统不断的调用onDraw方法去重绘界面来实现一个动画的效果
public void move(View view){
TranslateAnimation animation = new TranslateAnimation(0,200,0,0);
animation.setDuration(1000);
animation.setFillAfter(true);
imageView.startAnimation(animation);
}
上断面代码简单实现了imageView的的X轴方向平移了200个像素。虽然实现了这个效果,只是重绘了动画,改变了显示的位子,并没有改变响应事件的位子(可以添加监听事件做测试),所以传统动画并不能做与用户有交互动作的效果,并且不断的调用onDraw方法耗费cpu资源加上只有4种动画效果。并不能满足现在用户的需求。因此谷歌在3.0之后提出了属性动画。
2、属性动画(谷歌3.0之后出来的):Animator,顾名思义,就是操作一个属性的get、set方法去真实的改变一个属性。
一些常用的API:alpha 透明度, rotation z轴旋转, rotationX x轴旋转,rotationY y轴旋转,translationX x水平偏移
//第一种
ObjectAnimator.ofFloat(imageView,"translationY",0F,200F).setDuration(1000).start();
ObjectAnimator.ofFloat(imageView,"translationX",0F,200F).setDuration(1000).start();
ObjectAnimator.ofFloat(imageView,"rotation",0F,360F).setDuration(1000).start();
//第二种
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationY",0F,200F);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationX",0F,200F);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation",0F,360F);
ObjectAnimator.ofPropertyValuesHolder(imageView,p1,p2,p3);
上面是二种方面实现了图片的动画效果,是什么效果可以自己去敲下,毕竟这么简单。
还有一种就是通过AnimatorSet集合去实现动画的执行顺序
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationY", 0F, 150F);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView,"translationX",0F,150F);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView,"rotation",0F,180F);
ObjectAnimator animator4 = ObjectAnimator.ofFloat(imageView,"X",0F,1F);
AnimatorSet set = new AnimatorSet();
// set.playTogether(animator1,animator2,animator3);同事执行
// set.playSequentially(animator1,animator2,animator3);案顺序执行
//先同时执行1和2,然后在执行3
set.play(animator1).with(animator2);
set.play(animator3).after(animator2);
set.play(animator4).after(animator3);
set.setDuration(1000);
set.start();
3、如何给一个动画设置监听事件呢?非常简单:
public void alphaClick(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"alpha",0F,1F);
animator.setDuration(1000);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Toast.makeText(MainActivity.this,"anmi end",Toast.LENGTH_SHORT).show();
}
});
animator.start();
}
点击控件,透明度在1秒的变化,1秒后,打印吐司。
4、接下来我们来实现一个小例子吧,
XML文件:很简单,就是就是放了7张图片,叠在一起
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/b"
/>
<ImageView
android:id="@+id/image_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/c"
/>
<ImageView
android:id="@+id/image_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/d"
/>
<ImageView
android:id="@+id/image_e"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/e"
/>
<ImageView
android:id="@+id/image_f"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/f"
/>
<ImageView
android:id="@+id/image_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/g"
/>
<ImageView
android:id="@+id/image_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:src="@mipmap/a"
/>
</FrameLayout>
下面是Java代码:也很简单,在onCreat中初始化imageView,并添加到list中,然后设置监听。
package com.dragon.httpdeom.httpdemo;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/8/26 0026.
*/
public class myActivity extends Activity implements View.OnClickListener {
private int[] res = {R.id.image_a,R.id.image_b,R.id.image_c,R.id.image_d,R.id.image_e,R.id.image_f,R.id.image_g};
private List<ImageView> imageViewList = new ArrayList<>();
private boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activit_my);
for (int i = 0; i <res.length ; i++) {
ImageView imageView = (ImageView) findViewById(res[i]);
imageView.setOnClickListener(this);
imageViewList.add(imageView);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.image_a:
if (flag){
startAnim();
}else {
stopAnim();
}
break;
default:
Toast.makeText(myActivity.this,"click"+ v.getId(),Toast.LENGTH_SHORT).show();
break;
}
}
private void stopAnim() {
for (int i = 1; i <res.length ; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),"translationY",i * 80,0F);
//设置动画完成时间
animator.setDuration(500);
//设置动画开始延迟
animator.setStartDelay(i * 300);
//设置动画速度效果,动画是速度interpolator,他可以定义动画的速度变化,从而实现更加复杂的动画效果
animator.setInterpolator(new BounceInterpolator());
animator.start();
flag =true;
}
}
private void startAnim() {
for (int i = 1; i <res.length ; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),"translationY",0F,i * 80);
animator.setDuration(500);
animator.setInterpolator(new BounceInterpolator());
animator.setStartDelay(i * 300);
animator.start();
flag =false;
}
}
}
上面实现的是小球直线效果,直线的效果自己去实现下,这里我贴下扇形的效果图也可以实现小球的扇形效果,如下代码:
float angle;
final int r = 380;
angle = (float) Math.PI / (2 * (res.length - 2));
for (int i = 1; i < res.length; i++) {
float xLength = (float) (r * Math.sin((i - 1) * angle));
float yLength = (float) (r * Math.cos((i - 1) * angle));
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageViewList.get(i),
"translationX", 0F, -xLength);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageViewList.get(i),
"translationY", 0F, -yLength);
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2);
set.setDuration(500);
set.setInterpolator(new BounceInterpolator());
set.setStartDelay(i * 200);
set.start();
flag = true;
效果图:
4、ValueAnimator:是ObjetAnimator的父类,ValueAnimator本身并不会作用任何一个属性也不会提供任何一种动画,是一个数值发生器(产生你想要的任何数值)。有了这个值就可以作用控件,比如x值不断增加,形成一个动画,看个例子就明白了:点击button,上面的文本就0增加到100;
public void ValueClick(View view){
final Button button = (Button) view;
ValueAnimator animator = ValueAnimator.ofInt(0,100);
animator.setDuration(5000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
button.setText(""+value);
}
});
其中也可以自定义数值,代码如下。
ValueAnimator animator1 = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
float x=(endValue.x-startValue.x)*fraction;
float y=(endValue.y-startValue.x)*fraction;
button.setX(x);
button.setY(y);
return null;
}
},new PointF(1, 1),new PointF(300,300));
animator1.setDuration(3000);
animator1.start();
效果图: 好了,完事!!喜欢交友的朋友可以留言!