android属性动画效果的实现之ObjectAnimator
1.引入
首先我们先看一段代码
ObjectAnimator animator = bjectAnimator.ofFloat(tv,"alpha",1,0,1);
animator.setDuration(2000);
animator.start();
这段代码实现透明度的改变,其中tvs是TextView对象,1-0-1表示从透明度的变化,用时2000ms。
2.基础知识
ObjectAnimator 的方法非常简单:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
这是使用的基本格式
- 第一个参数用于指定这个动画要操作的是哪个控件
- 第二个参数用于指定这个动画要操作这个控件的哪个属性
- 第三个参数是可变长参数,就是指这个属性值是从哪变到哪
那么可能有人会问,第二个参数都有什么呢?
正如上面代码写的alpha,是控制透明度的,我们知道TextView是有setAlpha()方法的,对的,你猜对, 这个参数正是跟Setter函数相关的。
在 View 中有关动画,总共有下面几组 set 方法:
//1、透明度:alpha
public void setAlpha(float alpha)
//2、旋转度数:rotation、rotationX、rotationY
public void setRotation(float rotation) //绕Z轴
public void setRotationX(float rotationX) //绕X轴
public void setRotationY(float rotationY) //绕Y轴
//3、平移:translationX、translationY
public void setTranslationX(float translationX) //沿X轴
public void setTranslationY(float translationY) //沿Y轴
//缩放:scaleX、scaleY
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)
也就是说第二个参数可以有以下几种:
alpha、rotation、rotationX、rotationY 、translationX、translationY、scaleX、scaleY
3.使用方法
(1)透明度
ObjectAnimator animator1 = ObjectAnimator.ofFloat(tv, "alpha", 1, 0, 1);
animator1.setDuration(2000);
animator1.start();
效果
(2)平移
沿x轴平移
ObjectAnimator animator2 = ObjectAnimator.ofFloat(tv, "translationX", 0, 360);
animator2.setDuration(1000);
animator2.start();
效果
沿y轴平移
ObjectAnimator animator3 = ObjectAnimator.ofFloat(tv, "translationY", 0, 360);
animator3.setDuration(1000);
animator3.start();
效果
(3)旋转
绕z轴旋转
ObjectAnimator animator4 = ObjectAnimator.ofFloat(tv, "rotation", 0, 360);
animator4.setDuration(1000);
animator4.start();
效果
绕x轴旋转
ObjectAnimator animator5 = ObjectAnimator.ofFloat(tv, "rotationX", 0, 360);
animator5.setDuration(1000);
animator5.start();
绕y轴旋转
ObjectAnimator animator6 = ObjectAnimator.ofFloat(tv, "rotationY", 0, 360);
animator6.setDuration(1000);
animator6.start();
(4)拉伸
沿x轴拉伸
ObjectAnimator animator7 = ObjectAnimator.ofFloat(tv, "scaleX", 0, 3, 1);
animator7.setDuration(1000);
animator7.start();
沿y轴拉伸
ObjectAnimator animator8 = ObjectAnimator.ofFloat(tv, "scaleY", 0, 3, 1);
animator8.setDuration(1000);
animator8.start();
4.Demo
为了更好的理解下面写两个小例子
(1)下拉动画实现
布局文件代码
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.ax.animation.animation1">
<ImageView
android:id="@+id/iv_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/b"/>
<ImageView
android:id="@+id/iv_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/c"/>
<ImageView
android:id="@+id/iv_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/d"/>
<ImageView
android:id="@+id/iv_e"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/e"/>
<ImageView
android:id="@+id/iv_f"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/f"/>
<ImageView
android:id="@+id/iv_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/g"/>
<ImageView
android:id="@+id/iv_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/h"/>
<ImageView
android:id="@+id/iv_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a"/>
</FrameLayout>
activity代码
public class animation1 extends AppCompatActivity implements View.OnClickListener{
private int []res = {R.id.iv_a, R.id.iv_b, R.id.iv_c, R.id.iv_d,
R.id.iv_e, R.id.iv_f, R.id.iv_g, R.id.iv_h};
private List<ImageView> imageViewList = new ArrayList<ImageView>();
private boolean isFold = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation1);
for (int i=0; i<res.length; i++){
ImageView iv = (ImageView) findViewById(res[i]);
iv.setOnClickListener(this);
imageViewList.add(iv);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_a:
if (isFold){
unfold();
}else {
fold();
}
isFold = !isFold;
break;
}
}
/**
* 展开
*/
private void unfold(){
for(int i=1; i<res.length; i++){
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
"translationY", 0f, i*100);
animator.setDuration(300); //设置持续时间
animator.setStartDelay(700-i*100); //设置延迟时间
animator.start();
}
}
/**
* 折叠
*/
private void fold(){
for(int i=1; i<res.length; i++){
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
"translationY", i*100, 0f);
animator.setDuration(300);
animator.setStartDelay(i*100);
animator.start();
}
}
}
实现效果
(2)圆形展开
布局文件
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:gravity="center"
tools:context="com.ax.animation.animation2">
<ImageView
android:id="@+id/iv_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/b"/>
<ImageView
android:id="@+id/iv_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/c"/>
<ImageView
android:id="@+id/iv_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/d"/>
<ImageView
android:id="@+id/iv_e"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/e"/>
<ImageView
android:id="@+id/iv_f"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/f"/>
<ImageView
android:id="@+id/iv_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/g"/>
<ImageView
android:id="@+id/iv_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:src="@drawable/h"/>
<ImageView
android:id="@+id/iv_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/a"/>
</FrameLayout>
activity文件
public class animation2 extends AppCompatActivity implements View.OnClickListener{
private int []res = {R.id.iv_a, R.id.iv_b, R.id.iv_c, R.id.iv_d,
R.id.iv_e, R.id.iv_f, R.id.iv_g, R.id.iv_h};
private List<ImageView> imageViewList = new ArrayList<ImageView>();
private boolean isFold = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation2);
for (int i=0; i<res.length; i++){
ImageView iv = (ImageView) findViewById(res[i]);
iv.setOnClickListener(this);
imageViewList.add(iv);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_a:
if (isFold){
unfold();
}else {
fold();
}
isFold = !isFold;
break;
}
}
/**
* 展开
*/
private void unfold(){
for(int i=1; i<res.length; i++){
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f, (float)(150*Math.cos(2*(i-1)*Math.PI/(res.length-1))));
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f, (float)(150*Math.sin(2*(i-1)*Math.PI/(res.length-1))));
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViewList.get(i), p1, p2);
animator.setDuration(100); //设置持续时间
animator.setStartDelay(i*100); //设置延迟时间
animator.setInterpolator(new BounceInterpolator());//设置弹跳效果插值器
animator.start();
}
}
/**
* 折叠
*/
private void fold(){
for(int i=1; i<res.length; i++){
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", (float)(150*Math.cos(2*(i-1)*Math.PI/(res.length-1))), 0f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", (float)(150*Math.sin(2*(i-1)*Math.PI/(res.length-1))), 0f);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViewList.get(i), p1, p2);
animator.setDuration(100);
animator.setStartDelay(i*100); //设置延迟时间
animator.setInterpolator(new BounceInterpolator());//设置弹跳效果插值器
animator.start();
}
}
}
实现效果