一、前言
在現今App泛濫的市場上,各種App的功能都是你抄我的我抄你的時候,想做一個精品的App沒有自己的風格,沒有讓用戶眼前一亮的功能,或是效果的話都留步住用戶了。隨時都可以被其他應用替代。現今到處都喊著app簡約而不簡單,用戶體驗至上的年代,但有幾個app能做到呢?可能當設計師想著想著就忘記了設計的初衷。
吐槽半天,今天來看一下樂動力的一個比較有意思的動畫效果,覺得挺爽的,然後剛好又想熟悉一下Android動畫的,就拿來練下手。
二、效果圖

三、動畫分解
1、中間一個變大變小的動畫
2、上下兩個箭頭不停的旋轉<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+ICAgICAgICAgICAgICAzoaLX89PSwb249tChtcTNvMassrvNo7XY0P3XqrKiuPrXxdfUtKu+zb/J0tS077W9wOAmIzIwMjg0O8a90sY8L3A+CjxwPiAgICAgICAgICAgICAgNKGiyc/D5rfWveLOqs7luPZJbWFnZXZpZXeyotbY0LRWaWV3R3JvdXC077W919S2qNLlxcXB0DwvcD4KPHA+PHN0cm9uZz7LxKGitPrC6zwvc3Ryb25nPjwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">package com.spring.ledongli;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
public class GuideView extends ViewGroup {
/**
* 左邊的圖片
*/
private ImageView left;
/**
* 右邊的圖片
*/
private ImageView right;
/**
* 上面的圖片
*/
private ImageView top;
/**
* 下面的圖片
*/
private ImageView bottom;
/**
* 中間的圖片 m
*/
private ImageView center;
/**
* 屏幕的寬度
*/
private int screenW;
/**
* 屏幕的高度
*/
private int screenH;
public GuideView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public GuideView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public GuideView(Context context) {
super(context);
init(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(screenW, screenH);
}
private List bitmaps = new ArrayList();
private void init(Context context){
left = new ImageView(context);
left.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.day));
bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.day));
right = new ImageView(context);
right.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.night));
bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.night));
top = new ImageView(context);
top.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.up));
bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.up));
bottom = new ImageView(context);
bottom.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.down));
bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.down));
center = new ImageView(context);
center.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.animation_battery));
bitmaps.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.animation_battery));
screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();
screenH = ((Activity)context).getWindowManager().getDefaultDisplay().getHeight();
this.addView(center);
this.addView(left);
this.addView(right);
this.addView(top);
this.addView(bottom);
}
private LinearInterpolator interpolator = new LinearInterpolator();
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
//五個控件的布局
center.layout(screenW/2-bitmaps.get(4).getWidth()/2, screenH/2-bitmaps.get(4).getHeight()/2,
screenW/2+bitmaps.get(4).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2);
top.layout(screenW/2-bitmaps.get(2).getWidth()/2,screenH/2-bitmaps.get(4).getHeight()/2-bitmaps.get(2).getHeight()+bitmaps.get(2).getWidth()/2/4,
screenW/2+bitmaps.get(2).getWidth()/2, screenH/2-bitmaps.get(4).getHeight()/2+bitmaps.get(2).getWidth()/2/4);
left.layout(screenW/2-bitmaps.get(0).getWidth()*2-bitmaps.get(0).getWidth()/4, screenH/2-bitmaps.get(0).getHeight()/2,
screenW/2-bitmaps.get(0).getWidth()-bitmaps.get(0).getWidth()/4, screenH/2+bitmaps.get(0).getHeight()/2);
right.layout(screenW/2+bitmaps.get(1).getWidth()+bitmaps.get(1).getHeight()/4, screenH/2-bitmaps.get(1).getHeight()/2,
screenW/2+bitmaps.get(1).getWidth()*2+bitmaps.get(1).getHeight()/4, screenH/2+bitmaps.get(1).getHeight()/2);
bottom.layout(screenW/2-bitmaps.get(3).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2-bitmaps.get(3).getWidth()/2/4,
screenW/2+bitmaps.get(3).getWidth()/2, screenH/2+bitmaps.get(4).getHeight()/2+bitmaps.get(3).getHeight()-bitmaps.get(3).getWidth()/2/4);
playCenter();
playTop();
playBottom();
playLeft();
playRight();
}
/**
* 右邊的動畫
*/
private void playRight() {
//混合動畫
AnimationSet animationSet = new AnimationSet(false);
RotateAnimation rotateRight = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-right.getLeft(), Animation.ABSOLUTE, (right.getBottom()-right.getTop())/2);
RotateAnimation rotateSelf = new RotateAnimation(0, -359, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);
//播放時間
rotateSelf.setDuration(10*1000);
//播放加速的模式
rotateSelf.setInterpolator(interpolator);
//設置無限循環
rotateSelf.setRepeatCount(-1);
rotateRight.setDuration(10*1000);
rotateRight.setRepeatCount(-1);
rotateRight.setInterpolator(interpolator);
animationSet.addAnimation(rotateSelf);
animationSet.addAnimation(rotateRight);
//播放混合動畫
right.startAnimation(animationSet);
}
/**
* 左邊的動畫
*/
private void playLeft() {
AnimationSet animationSet = new AnimationSet(false);
RotateAnimation rotateLeft = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-left.getLeft(), Animation.ABSOLUTE, (left.getBottom()-left.getTop())/2);
rotateLeft.setDuration(10*1000);
rotateLeft.setInterpolator(interpolator);
rotateLeft.setRepeatCount(-1);
RotateAnimation rotateSelf = new RotateAnimation(0, -359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateSelf.setDuration(10*1000);
rotateSelf.setRepeatCount(-1);
rotateSelf.setInterpolator(interpolator);
animationSet.addAnimation(rotateSelf);
animationSet.addAnimation(rotateLeft);
left.startAnimation(animationSet);
}
/**
* 下面的動畫
*/
private void playBottom() {
RotateAnimation rotateBottom = new RotateAnimation(0, 359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.ABSOLUTE,screenH/2-bottom.getTop());
rotateBottom.setDuration(10*1000);
rotateBottom.setInterpolator(interpolator);
rotateBottom.setRepeatCount(-1);
bottom.startAnimation(rotateBottom);
}
/**
* 上面的動畫
*/
private void playTop() {
RotateAnimation rotateAnimation = new RotateAnimation(0, 359, Animation.ABSOLUTE, screenW/2-top.getLeft(), Animation.ABSOLUTE, screenH/2-top.getTop());
rotateAnimation.setDuration(10*1000);
rotateAnimation.setInterpolator(interpolator);
rotateAnimation.setRepeatCount(-1);
top.startAnimation(rotateAnimation);
}
/**
* 中間的View動畫播放
*/
private void playCenter() {
AnimationSet animationSet = new AnimationSet(false);
ScaleAnimation scaleSmall = new ScaleAnimation(1.0f, 0.6f, 1.0f, 0.6f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ScaleAnimation scaleBig = new ScaleAnimation(1.0f, 5.0f/3, 1.0f, 5.0f/3,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleBig.setDuration(2*1000);
scaleBig.setInterpolator(interpolator);
scaleSmall.setDuration(2*1000);
scaleSmall.setStartOffset(2*1000);
scaleSmall.setRepeatCount(-1);
scaleSmall.setFillEnabled(true);
scaleSmall.setFillAfter(true);
scaleBig.setStartOffset(2*1000);
scaleBig.setRepeatCount(-1);
scaleBig.setFillEnabled(true);
scaleBig.setFillAfter(true);
scaleSmall.setInterpolator(interpolator);
animationSet.addAnimation(scaleBig);
animationSet.addAnimation(scaleSmall);
center.startAnimation(animationSet);
}
}
五、遇到的問題
寫這個小Demo主要的問題在兩個小太陽的自傳和中點循轉的結合,這方面在網上的資料也比較少,自己做了幾個嘗試最終完成。要很好的理解pivotXType裡的三種方式Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT、Animation.ABSOLUT,第一種多用於基於自己View的幾分之幾來定值,第二種是基於父控件來定位,第三種是絕對定位,圖片的基點在右上角,然後算偏移的值定位旋轉的中間。
六、項目地址
http://download.csdn.net/detail/hxc2008q/6931227