Android动画效果可以给人一种视觉感受,下面我将列举一些常用的动画效果。
1.在图片显示过程中使用动画效果,可以给人一种感觉。比如渐进渐出的效果。
下面贴上代码。
mSwitcher = (ImageSwitcher) findViewById(R.id.switcher); mSwitcher.setFactory(this); mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
android.R.anim.fade_in, android.R.anim.fade_out两种动画效果是系统自带的效果。
2.下面介绍自定义的动画效果。
// 實現動畫效果 Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake); findViewById(R.id.pw).startAnimation(shake);
里面用到的shake.xml文件,存放在anim目录下面。代码如下:
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="1000" android:interpolator="@anim/cycle_7" />
而里面的cycle_7.xml,代码如下所示:
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />
下面介绍APIDEMO中的动画效果。
第一种ViewFlipper中各背景图片的切换效果。
public class Animation2 extends Activity implements AdapterView.OnItemSelectedListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.animation_2); mFlipper = ((ViewFlipper) this.findViewById(R.id.flipper)); mFlipper.startFlipping(); Spinner s = (Spinner) findViewById(R.id.spinner); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mStrings); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); s.setAdapter(adapter); s.setOnItemSelectedListener(this); } public void onItemSelected(AdapterView parent, View v, int position, long id) { switch (position) { case 0: mFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_out)); break; case 1: mFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); break; case 2: mFlipper.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); break; default: mFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.hyperspace_out)); break; } } public void onNothingSelected(AdapterView parent) { } private String[] mStrings = { "Push up", "Push left", "Cross fade", "Hyperspace"}; private ViewFlipper mFlipper; }
animation_2.xml文件如下:
<ViewFlipper android:id="@+id/flipper" android:layout_width="match_parent" android:layout_height="wrap_content" android:flipInterval="2000" android:layout_marginBottom="20dip" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:textSize="26sp" android:text="@string/animation_2_text_1"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:textSize="26sp" android:text="@string/animation_2_text_2"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:textSize="26sp" android:text="@string/animation_2_text_3"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:textSize="26sp" android:text="@string/animation_2_text_4"/> </ViewFlipper> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dip" android:text="@string/animation_2_instructions" /> <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" />
Animation3.java中源码如下:
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.view; // Need the following import to get access to the app resources, since this // class is in a sub-package. import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; public class Animation3 extends Activity implements AdapterView.OnItemSelectedListener { private static final String[] INTERPOLATORS = { "Accelerate", "Decelerate", "Accelerate/Decelerate", "Anticipate", "Overshoot", "Anticipate/Overshoot", "Bounce" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.animation_3); // android.R.layout.simple; Spinner s = (Spinner) findViewById(R.id.spinner); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, INTERPOLATORS); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); s.setAdapter(adapter); s.setOnItemSelectedListener(this); } public void onItemSelected(AdapterView parent, View v, int position, long id) { final View target = findViewById(R.id.target); final View targetParent = (View) target.getParent();//得到上一级 Animation a = new TranslateAnimation(0.0f, targetParent.getWidth() - target.getWidth() - targetParent.getPaddingLeft() - targetParent.getPaddingRight(), 0.0f, 0.0f); a.setDuration(1000); a.setStartOffset(300); a.setRepeatMode(Animation.RESTART);//restart a.setRepeatCount(Animation.INFINITE); switch (position) { case 0: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.accelerate_interpolator)); break; case 1: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.decelerate_interpolator)); break; case 2: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.accelerate_decelerate_interpolator)); break; case 3: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.anticipate_interpolator)); break; case 4: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.overshoot_interpolator)); break; case 5: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.anticipate_overshoot_interpolator)); break; case 6: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.bounce_interpolator)); break; } target.startAnimation(a); } public void onNothingSelected(AdapterView parent) { } }
animation_3.xml文件源码如下:
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2009 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="10dip" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false"> <TextView android:id="@+id/target" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="26sp" android:text="@string/animation_3_text"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dip" android:layout_marginBottom="5dip" android:text="@string/animation_2_instructions" /> <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
3D效果,贴上代码。
Rotate3dAnimation.java
public class Rotate3dAnimation extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private final float mDepthZ; private final boolean mReverse; private Camera mCamera; /** * Creates a new 3D rotation on the Y axis. The rotation is defined by its * start angle and its end angle. Both angles are in degrees. The rotation * is performed around a center point on the 2D space, definied by a pair * of X and Y coordinates, called centerX and centerY. When the animation * starts, a translation on the Z axis (depth) is performed. The length * of the translation can be specified, as well as whether the translation * should be reversed in time. * * @param fromDegrees the start angle of the 3D rotation * @param toDegrees the end angle of the 3D rotation * @param centerX the X center of the 3D rotation * @param centerY the Y center of the 3D rotation * @param reverse true if the translation should be reversed, false otherwise */ public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }
Transition3d.java
package com.example.android.apis.animation; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.ArrayAdapter; import android.widget.AdapterView; import android.widget.ImageView; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; /** * This sample application shows how to use layout animation and various * transformations on views. The result is a 3D transition between a * ListView and an ImageView. When the user clicks the list, it flips to * show the picture. When the user clicks the picture, it flips to show the * list. The animation is made of two smaller animations: the first half * rotates the list by 90 degrees on the Y axis and the second half rotates * the picture by 90 degrees on the Y axis. When the first half finishes, the * list is made invisible and the picture is set visible. */ public class Transition3d extends Activity implements AdapterView.OnItemClickListener, View.OnClickListener { private ListView mPhotosList; private ViewGroup mContainer; private ImageView mImageView; // Names of the photos we show in the list private static final String[] PHOTOS_NAMES = new String[] { "Lyon", "Livermore", "Tahoe Pier", "Lake Tahoe", "Grand Canyon", "Bodie" }; // Resource identifiers for the photos we want to display private static final int[] PHOTOS_RESOURCES = new int[] { R.drawable.photo1, R.drawable.photo2, R.drawable.photo3, R.drawable.photo4, R.drawable.photo5, R.drawable.photo6 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.animations_main_screen); mPhotosList = (ListView) findViewById(android.R.id.list); mImageView = (ImageView) findViewById(R.id.picture); mContainer = (ViewGroup) findViewById(R.id.container); // Prepare the ListView final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, PHOTOS_NAMES); mPhotosList.setAdapter(adapter); mPhotosList.setOnItemClickListener(this); // Prepare the ImageView mImageView.setClickable(true); mImageView.setFocusable(true); mImageView.setOnClickListener(this); // Since we are caching large views, we want to keep their cache // between each animation mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE); } /** * Setup a new 3D rotation on the container view. * * @param position the item that was clicked to show a picture, or -1 to show the list * @param start the start angle at which the rotation must begin * @param end the end angle of the rotation */ private void applyRotation(int position, float start, float end) { // Find the center of the container final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; // Create a new 3D rotation with the supplied parameter // The animation listener is used to trigger the next animation final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true); rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new DisplayNextView(position)); mContainer.startAnimation(rotation); } public void onItemClick(AdapterView parent, View v, int position, long id) { // Pre-load the image then start the animation mImageView.setImageResource(PHOTOS_RESOURCES[position]); applyRotation(position, 0, 90); } public void onClick(View v) { applyRotation(-1, 180, 90); } /** * This class listens for the end of the first half of the animation. * It then posts a new action that effectively swaps the views when the container * is rotated 90 degrees and thus invisible. */ private final class DisplayNextView implements Animation.AnimationListener { private final int mPosition; private DisplayNextView(int position) { mPosition = position; } public void onAnimationStart(Animation animation) { } public void onAnimationEnd(Animation animation) { mContainer.post(new SwapViews(mPosition)); } public void onAnimationRepeat(Animation animation) { } } /** * This class is responsible for swapping the views and start the second * half of the animation. */ private final class SwapViews implements Runnable { private final int mPosition; public SwapViews(int position) { mPosition = position; } public void run() { final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; Rotate3dAnimation rotation; if (mPosition > -1) { mPhotosList.setVisibility(View.GONE); mImageView.setVisibility(View.VISIBLE); mImageView.requestFocus(); rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false); } else { mImageView.setVisibility(View.GONE); mPhotosList.setVisibility(View.VISIBLE); mPhotosList.requestFocus(); rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false); } rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new DecelerateInterpolator()); mContainer.startAnimation(rotation); } } }
animations_main_screen.xml文件
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@android:id/list" android:persistentDrawingCache="animation|scrolling" android:layout_width="match_parent" android:layout_height="match_parent" android:layoutAnimation="@anim/layout_bottom_to_top_slide" /> <ImageView android:id="@+id/picture" android:scaleType="fitCenter" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" /> </FrameLayout>
layout_bottom_to_top_slide.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2007 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="30%" android:animationOrder="reverse" android:animation="@anim/slide_right" />
slide_right.xml文件
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2007 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="@android:integer/config_shortAnimTime" /> </set>