Android View Animation 视图动画
在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
代码实现:
// 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) { } }); } }