本文在理解 http://blog.csdn.net/tianjian4592/article/details/45157787
的基础上,进行了部分优化,源码在http://download.csdn.net/detail/xiaomu123456/9685975,主要看StarActivity就行了
实际效果如下:


首先,要实现这样一幅动效图,基本上就是两个步骤:   第一,在背景上确定物体(图片中的星体,流星)的初始位置   第二,使物体进行移动,在此过程中要实时更新物体的参数信息,比如大小,亮度等
其次,对于图中的每一个实体对象,都需要以下基本信息    1.方向2.速度3.形态4.大小5.位置6.物体宽度,高度7透明度等
具体定义如下: public class StarInfo {
    //方向     public final static int LEFT = 0;     public final static int RIGHT = 1;     public final static int TOP = 2;     public final static int BOTTOM = 3;     public static final int RIGHT_BOTTOM = 4;
    //速度,实际上相当于在背景上移动的距离(像素)     public static final int LOW_SPEED = 1;     public static final int MID_SPEED = 2;     public static final int HIGTH_SPEED = 3;
    public Bitmap mBitmap;//形态     public int mWidth;//物体宽度     public int mHeight;//物体高度     public Rect mSrcRect;//自身所占的矩形区域
    // 大小     float sizePercent;     // x位置     int xLocation;     // y位置     int yLocation;     // 透明度     float alpha;     // 漂浮方向     int direction;     // 漂浮速度     int speed; }
在图中第一种对象为星体,定义如下:
public class CircleStar extends StarInfo {
    public static final int STAR_TYPE_1 = 101;     public static final int STAR_TYPE_2 = 102;     public static final int STAR_TYPE_3 = 103;
    private Context mContext;
    public CircleStar(Context context,int type){         this.mContext = context;         initBitmap(type);     }
    public void initBitmap( int type ){         switch (type){             case STAR_TYPE_1:                 mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.drawable.small_start1))                         .getBitmap();                 break;             case STAR_TYPE_2:                 mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.drawable.small_star2))                         .getBitmap();                 break;             case STAR_TYPE_3:                 mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.drawable.small_star2))                         .getBitmap();                 break;             default:                 mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.drawable.small_start1))                         .getBitmap();                 break;         }         mWidth = mBitmap.getWidth();         mHeight = mBitmap.getHeight();         mSrcRect = new Rect(0,0, mWidth, mHeight);     }
}
在图中第二种对象为流星,定义如下:
public class FallingStar extends StarInfo {
    private Context mContext;
    public FallingStar(Context context){         this.mContext = context;         initBitmap();     }
    public void initBitmap(){         mBitmap = ((BitmapDrawable) mContext.getResources().getDrawable(R.drawable.light_star_1))                 .getBitmap();         mWidth = mBitmap.getWidth();         mHeight = mBitmap.getHeight();         mSrcRect = new Rect(0,0, mWidth, mHeight);     } } 最后在view中展示动画效果:
public class StarView extends View {
    private final static int mStarCount = 200;//背景图添加了200个实体对象     private List mStarInfos = new ArrayList();     private Bitmap mBackgoundBitmap;//背景图片     private int mBackgoundWidth;     private int mBackgoundHeight;     private int mTotalWidth,mTotalHeight;//实际上是背景宽度和高度     private Paint mPaint;
    public StarView(Context context) {         this(context,null);     }
    public StarView(Context context, AttributeSet attrs) {         this(context, attrs,0);     }
    public StarView(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);         initData();         initStarInfo();     }
    private void initData() {         //背景         mBackgoundBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.bg_star))                 .getBitmap();         mBackgoundWidth = mBackgoundBitmap.getWidth();         mBackgoundHeight = mBackgoundBitmap.getHeight();         mTotalWidth = mBackgoundWidth;         mTotalHeight = mBackgoundHeight;         this.setBackgroundResource(R.drawable.bg_star);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);         mPaint.setFilterBitmap(true);         mPaint.setDither(true);     }
    /**      * 获取星球大小      */     private float getStarSize(float start, float end) {         float nextFloat = (float) Math.random();         if (start < nextFloat && nextFloat < end) {             return nextFloat;         } else {             // 如果不处于想要的数据段,则再随机一次,因为不断递归有风险             return (float) Math.random();         }     }
    /**      * 初始化星球信息      */     private void initStarInfo() {
        StarInfo starInfo = null;         for (int i = 0; i < mStarCount; i++) {
            if( i % 2 == 0 ){                 starInfo = new CircleStar(getContext(),CircleStar.STAR_TYPE_1);//星体1             }else if(i % 3 == 0){                 starInfo = new CircleStar(getContext(),CircleStar.STAR_TYPE_2);//星体2             }else{                 starInfo = new FallingStar(getContext());//流星             }
            //共有属性             starInfo.sizePercent = getStarSize(0.1f, 0.2f);             getStarSpeed(starInfo);             starInfo.alpha = getStarSize(0.3f, 0.5f);             starInfo.xLocation = (int) (getStarSize(0f,1f) * mTotalWidth);             starInfo.yLocation = (int) (getStarSize(0f,1f) * mTotalHeight);
            if( starInfo instanceof FallingStar ){                 starInfo.direction = StarInfo.RIGHT_BOTTOM;             }else {                 starInfo.direction = getStarDirection();             }             mStarInfos.add(starInfo);         }     }
    /**      *在画布上画出star      */     private void drawStarDynamic(StarInfo starInfo, Canvas canvas, Paint paint) {         int xLocation = (int) ( starInfo.xLocation / starInfo.sizePercent);         int yLocation = (int) ( starInfo.yLocation / starInfo.sizePercent);
        Bitmap bitmap = starInfo.mBitmap;         Rect srcRect = starInfo.mSrcRect;         Rect destRect = new Rect();         destRect.set(xLocation, yLocation, xLocation + starInfo.mWidth, yLocation + starInfo.mHeight);
        paint.setAlpha((int) (starInfo.alpha * 255));         canvas.save();         canvas.scale(starInfo.sizePercent, starInfo.sizePercent);         canvas.drawBitmap(bitmap, srcRect, destRect, paint);         canvas.restore();
    }
    /**      *改变star的参数信息(比如速度,透明度,大小等),在画布上移动star      */     private void resetStarFloat(StarInfo starInfo) {         switch (starInfo.direction) {             case StarInfo.LEFT:                 starInfo.xLocation -= starInfo.speed;                 if( starInfo.xLocation <= 0 ){                     starInfo.direction = StarInfo.RIGHT;                 }                 break;             case StarInfo.RIGHT:                 starInfo.xLocation += starInfo.speed;                 if( starInfo.xLocation >= mTotalWidth ){                     starInfo.direction = StarInfo.LEFT;                 }                 break;             case StarInfo.TOP:                 starInfo.yLocation -= starInfo.speed;                 if( starInfo.yLocation <= 0 ){                     starInfo.direction = StarInfo.BOTTOM;                 }                 break;             case StarInfo.BOTTOM:                 starInfo.yLocation += starInfo.speed;                 if( starInfo.yLocation >= mTotalHeight ){                     starInfo.direction = StarInfo.TOP;                 }                 break;             case StarInfo.RIGHT_BOTTOM:                 starInfo.xLocation += starInfo.speed;                 starInfo.yLocation += starInfo.speed;                 starInfo.alpha += 0.003;                 starInfo.sizePercent += 0.003;                 if( starInfo.xLocation  >= mTotalWidth ){                     starInfo.xLocation = 0;                     starInfo.sizePercent = 0.1f;                     starInfo.alpha = getStarSize(0.0f,0.3f);                 }else if( starInfo.yLocation >= mTotalHeight ){                     starInfo.yLocation = 0;                     starInfo.sizePercent = 0.1f;                     starInfo.alpha = getStarSize(0.0f,0.3f);                 }                 if( starInfo.alpha >= 1.0 ){                     starInfo.alpha = 1;                 }                 if( starInfo.sizePercent >= 0.6 ){                     starInfo.sizePercent = 0.6f;                 }
                break;             default:                 break;         }     }
    @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         super.onMeasure(widthMeasureSpec, heightMeasureSpec);     }
    @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         for (int i = 0; i < mStarInfos.size(); i++) {             drawStarDynamic(mStarInfos.get(i), canvas, mPaint);             resetStarFloat(mStarInfos.get(i));         }         postInvalidate();     }
    /**      * 初始化漂浮速度      */     private int getStarSpeed(StarInfo starInfo){         Random random = new Random();         int randomSpeed = random.nextInt(3);         switch (randomSpeed) {             case 0:                 starInfo.speed = StarInfo.LOW_SPEED;                 break;             case 1:                 starInfo.speed = StarInfo.MID_SPEED;                 break;             case 2:                 starInfo.speed = StarInfo.HIGTH_SPEED;                 break;             default:                 starInfo.speed = StarInfo.MID_SPEED;                 break;         }         return starInfo.speed;     }
    /**      * 初始化星球运行方向      */     public int getStarDirection() {         Random random = new Random();         int randomInt = random.nextInt(4);         int direction = 0;         switch (randomInt) {             case 0:                 direction = StarInfo.LEFT;                 break;             case 1:                 direction = StarInfo.RIGHT;                 break;             case 2:                 direction = StarInfo.TOP;                 break;             case 3:                 direction = StarInfo.BOTTOM;                 break;
            default:                 break;         }         return direction;     }
}

更多相关文章

  1. NDK学习笔记(十四) 使用AVILib+window创建一个AVI视频播放器
  2. Android(安卓)软键盘之 windowSoftInputMode 分析
  3. Android开发之自定义相机设定照片和预览参数问题
  4. android修改图片(修改图片大小,图片旋转,图片平移)
  5. [Android]【安卓】在代码中实时改变控件的大小
  6. Android动态设置控件大小
  7. Android文件、内存、SDCard管理常用工具类、方法
  8. Android(安卓)TextView自适应文字大小
  9. 计算Android(安卓)App占用的各种空间大小

随机推荐

  1. AndroidManifest.xml 中application 的 a
  2. Android实现全屏
  3. android ant 打包报错:  [aapt] invalid
  4. Android键盘属性
  5. FAQ_05_查看 android 设备 ip
  6. android studio 打包 so 库
  7. Android SDK和最新ADT下载地址 + 环境搭
  8. Mono for Android—初体验之“电话拨号器
  9. 关于Android(安卓)Pie(Android(安卓)9.0),你
  10. 全屏、小屏、横屏、竖屏的切换