在Android3.0之前,Android动画效果分为Tween Animation补间动画和Frame Animation逐帧动画(也有人称Drawable Animation),统称为视图动画。
透明动画效果AlphaAnimation
界面配置就是在点击按钮时触发效果,点击内的代码如下:
AlphaAnimation animation = new AlphaAnimation(0,1);
animation.setDuration(1000);
v.startAnimation(animation);
也可以使用xml文件来配置动画效果,在res目录下创建anim文件夹,在其中配置anim.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="1"
android:duration="1000">
</alpha>
然后在代码中
v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim));
代码实现:
// RotateAnimation animation = new RotateAnimation(0,360);//原点旋转
// RotateAnimation animation = new RotateAnimation(0,360,100,50);//指定点旋转
RotateAnimation animation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);//自身中心点旋转
animation.setDuration(1000);
v.startAnimation(animation);
xml实现:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
位移动画TranslateAnimation
代码:
TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 200);//目标点相对于自身的增量
animation.setDuration(1000);
v.startAnimation(animation);
xml:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="200"
android:fromYDelta="0"
android:toYDelta="200"
android:duration="1000">
</translate>
缩放动画ScaleAnimation
代码:
// ScaleAnimation animation = new ScaleAnimation(0,1,0,1);
// ScaleAnimation animation = new ScaleAnimation(0,1,0,1,100,50);
ScaleAnimation animation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(1000);
v.startAnimation(animation);
xml:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:duration="1000"
android:pivotX="50%"
android:pivotY="50%">
</scale>
动画效果混合
代码:
AnimationSet animationSet = new AnimationSet(true);
animationSet.setDuration(1000);
AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);
alphaAnimation.setDuration(1000);
animationSet.addAnimation(alphaAnimation);
TranslateAnimation translateAnimation = new TranslateAnimation(0,200,0,200);
translateAnimation.setDuration(1000);
animationSet.addAnimation(translateAnimation);
v.startAnimation(animationSet);
xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:duration="1000">
<alpha android:fromAlpha="0" android:toAlpha="1"/>
<translate android:fromXDelta="0" android:toXDelta="200"
android:fromYDelta="0" android:toYDelta="200"/>
</set>
如果想要对动画事件进行监听,只需让动画对象实现AnimationListener接口即可:
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,"Animation end",Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
自定义动画效果
我们可以通过继承Animation来自定义一个动画效果:
代码实现:
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class CustomAnim extends Animation {
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
// System.out.println(">>>>>>>>>>>>");
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
// System.out.println(interpolatedTime);
// t.setAlpha(interpolatedTime);
// t.getMatrix().setTranslate(200*interpolatedTime,200*interpolatedTime);
t.getMatrix().setTranslate((float) (Math.sin(interpolatedTime*20)*50),0);//20周期 越大越快 50 振幅 越大越宽
super.applyTransformation(interpolatedTime, t);
}
}
使用:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private CustomAnim customAnim;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customAnim = new CustomAnim();
customAnim.setDuration(1000);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.startAnimation(customAnim);
}
});
}
}
视图动画除了用在控件上在布局上也可以使用,如下图的效果:
实现代码如下:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.LayoutAnimationController;
import android.view.animation.ScaleAnimation;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout view = (LinearLayout) View.inflate(this, R.layout.activity_main, null);
setContentView(view);
ScaleAnimation sa = new ScaleAnimation(0,1,0,1);
sa.setDuration(2000);
LayoutAnimationController lac = new LayoutAnimationController(sa,0.5f);//0.5f 延迟 一个一个出来
lac.setOrder(LayoutAnimationController.ORDER_REVERSE);//出来的顺序
view.setLayoutAnimation(lac);
}
}
在布局内容改变时官方也为我们设置了一个简单的动画效果,只需在页面布局中添加
android:animateLayoutChanges="true"
布局动画也可以使用在ListView中:
代码:
public class MainActivity extends ListActivity {
private ArrayAdapter<String> adapter;
private LayoutAnimationController lac;
private ScaleAnimation sa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,new String[]{"Hello","World","Android"});
setListAdapter(adapter);
sa = new ScaleAnimation(0,1,0,1);
sa.setDuration(1000);
lac = new LayoutAnimationController(sa,0.5f);
getListView().setLayoutAnimation(lac);
}
}
该效果也可以使用xml文件实现:
先创建单个动画scale.xml:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:duration="1000">
</scale>
再创建layoutAnimation文件list_anim.xml:
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/scale"
android:delay="0.5">
</layoutAnimation>
使用时直接放在布局文件中:
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/list"
android:layoutAnimation="@anim/list_anim"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
视图动画应用---2D翻转
代码如下:
<?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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/ivA"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:src="@drawable/image_a" />
<ImageView
android:id="@+id/ivB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:src="@drawable/image_b" />
</FrameLayout>
package com.jikexueyuan.card2d;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView imageA, imageB;
private ScaleAnimation sato0 = new ScaleAnimation(1, 0, 1, 1, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.5f);
private ScaleAnimation sato1 = new ScaleAnimation(0, 1, 1, 1, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.5f);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
findViewById(R.id.root).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (imageA.getVisibility() == View.VISIBLE){
imageA.startAnimation(sato0);
} else {
imageB.startAnimation(sato0 );
}
}
});
}
private void showImageA() {
imageA.setVisibility(View.VISIBLE);
imageB.setVisibility(View.INVISIBLE);
}
private void showImageB() {
imageA.setVisibility(View.INVISIBLE);
imageB.setVisibility(View.VISIBLE);
}
private void initView() {
imageA = (ImageView) findViewById(R.id.ivA);
imageB = (ImageView) findViewById(R.id.ivB);
showImageA();
sato0.setDuration(500);
sato1.setDuration(500);
sato0.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (imageA.getVisibility() == View.VISIBLE){
imageA.setAnimation(null);
showImageB();
imageB.startAnimation(sato1);
} else {
imageB.setAnimation(null);
showImageA();
imageA.startAnimation(sato1);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}