Android 的漂浮动画,下雪动画

因工作需要最近在研究了动画,下文的代码取自http://blog.csdn.net/tianjian4592/article/details/45157787,原文没有源码,但是博主把关键代码都给了,此人很牛,动画绘制这块文章写的很细,容易理解,建议去看下,自己稍作修改,调通,作为笔记,来解决他人思路,来实现工作需求;先看下效果:

1.先得了解下canvas.drawBitmap(mBitmap, mSrcRect, mDestRect, mBitPaint);

在绘制图片时,使用,参数分别,图片bitmap,绘制bitmap自己的区域,绘制bitmap在手机上显示位置区域,画笔;

mSrcRect,mDestRect都是Rect(int left, int top, int right, int bottom) 的对象;

2.思路

a.漂浮的图片,可能是小球,星星,雪花之类的,根据需求,选若干个不同小图片,先称之他们漂浮的星星;

b.根据效果,漂浮图片设置其实有关数据,像坐标,大小,透明度,移动速度进水,移动方向等;

c.然后初始化以上数据,生成批量小球,进行绘制;

d.开设个线程或handle造成定时器,来不断刷新,同时修改漂浮星星属性,

3.代码

a.定义一个继承View的类,初始化画笔,所需若干星星,设置不同速度

 private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 防抖动
        paint.setDither(true);
        // 开启图像过滤
        paint.setFilterBitmap(true);
    }
/**
     * 设置动画目标,三张大小不同,样式不一,为了美观
     * init bitmap info
     */
    private void initBitmapInfo() {
        mStarOne = ((BitmapDrawable) mResources.getDrawable(R.drawable.star2)).getBitmap();
        mStarOneWidth = mStarOne.getWidth();
        mStarOneHeight = mStarOne.getHeight();

        mStarTwo = ((BitmapDrawable) mResources.getDrawable(R.drawable.star1)).getBitmap();
        mStarTwoWidth = mStarTwo.getWidth();
        mStarTwoHeight = mStarTwo.getHeight();

        mStarThree = ((BitmapDrawable) mResources.getDrawable(R.drawable.star3)).getBitmap();
        mStarThreeWidth = mStarThree.getWidth();
        mStarThreeHeight = mStarThree.getHeight();
    }
 //定义三种不同快慢的漂浮速度
    private void initData(Context context) {
        mResources = getResources();
        DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();

        mTotalWidth = dm.widthPixels;
        mTotalHeight = dm.heightPixels;
        Log.i(TAG, "mTotalWidth=" + mTotalWidth + "--1--mTotalHeight=" + mTotalHeight);
        //设置三个不同大小的速度值
        mFloatTransLowSpeed = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0.5f,
                mResources.getDisplayMetrics());
        mFloatTransMidSpeed = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0.75f,
                mResources.getDisplayMetrics());
        mFloatTransFastSpeed = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f,
                mResources.getDisplayMetrics());
    }

b.初始化星星,因为在构造方法里把一些基本数据初始化结束后,接着会进行测量,我把初始化星星方法放在

onMeasure方法了

 /**
     * 初始化星星信息
     */
    private void initStarInfo() {

        StarInfo starInfo = null;
        Random random = new Random();
        for (int i = 0; i < mFloatCount; i++) {
            // 获取星星大小比例
            float starSize = getStarSize(0.4f, 0.8f);
            //小球的坐标
            float[] starLocation = STAR_LOCATION[i];
            starInfo = new StarInfo();
            // 初始化星星大小
            starInfo.sizePercent = starSize;
            // 初始化漂浮速度
            int randomSpeed = random.nextInt(3);
            switch (randomSpeed) {
                case 0:
                    starInfo.speed = mFloatTransLowSpeed;
                    break;
                case 1:
                    starInfo.speed = mFloatTransMidSpeed;
                    break;
                case 2:
                    starInfo.speed = mFloatTransFastSpeed;
                    break;
                default:
                    starInfo.speed = mFloatTransMidSpeed;
                    break;
            }
            // 初始化星星透明度
            starInfo.alpha = getStarSize(0.3f, 0.8f);
            // 初始化星星位置
            starInfo.xLocation = (int) (starLocation[0] * mTotalWidth);
            starInfo.yLocation = (int) (starLocation[1] * mTotalHeight);
            Log.i(TAG, "xLocation = " + starInfo.xLocation + "--yLocation = "
                    + starInfo.yLocation);
            Log.i(TAG, "stoneSize = " + starSize + "---stoneAlpha = "
                    + starInfo.alpha);
            // 初始化星星位置
            starInfo.direction = getStarDirection();
            mStarInfos.add(starInfo);
        }
    }

STAR_LOCATION[]数组的人为的确定星星占手机屏幕大小比例的位置,自己试过随机生成一些数据,但是有时就扎堆了,应该找个手机屏幕上随机不重复生成点坐标的算法,正在思考,有会的,给我说下,学习下

c.设置星星的移动方向,这里只是常态化的左右上下,对角线的方向,自己可以添加其他轨迹方向

 /**
     * 不同移动轨迹,除过左右上下,也可以定义其他方向,如对角线,曲线之类的
     * 初始化星星运行方向
     */
    private int getStarDirection() {
        int randomInt;
        Random random = new Random();
        if(floatTyep==100){
            randomInt = random.nextInt(3);
        }else {
            randomInt=floatTyep;
        }
        int direction = 0;
        switch (randomInt) {
            case 0:
                direction = LEFT;
                break;
            case 1:
                direction = RIGHT;
                break;
            case 2:
                direction = TOP;
                break;
            case 3:
                direction = BOTTOM;
                break;
            case 4:
                direction = FREE_POINT;
                break;
            default:
                break;
        }
        return direction;
    }

d.重复绘制时,修改小球的运动轨迹方向,添加case类型,比如一些正余弦轨迹,在手机上菱形运行,折线轨迹等;

private void resetStarFloat(StarInfo starInfo) {
        switch (starInfo.direction) {
            case LEFT:
                if (starInfo.xLocation < -20) {
                    starInfo.xLocation = mTotalWidth;
                } else {
                    starInfo.xLocation -= starInfo.speed;
                }

                break;
            case RIGHT:
                if (starInfo.xLocation > mTotalWidth+20) {
                    starInfo.xLocation = 0;
                } else {
                    starInfo.xLocation += starInfo.speed;
                }

                break;
            case TOP:
                if (starInfo.yLocation < -20) {
                    starInfo.yLocation = mTotalHeight;
                } else {
                    starInfo.yLocation -= starInfo.speed;
                }

                break;
            case BOTTOM:
                if (starInfo.yLocation > mTotalHeight+30) {
                    starInfo.yLocation = 0;
                } else {
                    starInfo.yLocation += starInfo.speed;
                }
                break;
            case FREE_POINT:

                if (starInfo.yLocation > mTotalHeight+30) {
                    starInfo.yLocation = 0;
                } else {
                    starInfo.yLocation += starInfo.speed;
                }

                if (starInfo.xLocation < -20) {
                    starInfo.xLocation = mTotalWidth;
                } else {
                    starInfo.xLocation -= starInfo.speed;
                }
                break;
            default:
                break;
        }
    }

上面的20,30是随便加的,是为了让星星跑到手机屏幕之外,再重新进入界面,否则直接运动到屏幕边界,重新开始,会闪的一下,效果不好;

e.进行绘制

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mStarInfos.size(); i++) {
            StarInfo starInfo = mStarInfos.get(i);
            drawStarDynamic(i, starInfo, canvas, paint);
        }
    }

    private void drawStarDynamic(int count, StarInfo starInfo,
                                 Canvas canvas, Paint paint) {
        resetStarFloat(starInfo);
        float starAlpha = starInfo.alpha;
        int xLocation = starInfo.xLocation;
        int yLocation = starInfo.yLocation;
        float sizePercent = starInfo.sizePercent;

        xLocation = (int) (xLocation / sizePercent);
        yLocation = (int) (yLocation / sizePercent);

        Bitmap bitmap = null;
        Rect srcRect = null;
        Rect destRect = new Rect();

        mStarOneSrcRect = new Rect(0, 0, mStarOneWidth, mStarOneHeight);
        if (count % 3 == 0) {

            bitmap = mStarOne;
            srcRect = mStarOneSrcRect;
            destRect.set(xLocation, yLocation,
                    xLocation + mStarOneWidth, yLocation
                            + mStarOneHeight);
        } else if (count % 2 == 0) {
            bitmap = mStarThree;
            srcRect = mStarThreeSrcRect;
            destRect.set(xLocation, yLocation, xLocation
                    + mStarThreeWidth, yLocation + mStarThreeHeight);
        } else {
            bitmap = mStarTwo;
            srcRect = mStarTwoSrcRect;
            destRect.set(xLocation, yLocation, xLocation
                    + mStarTwoWidth, yLocation + mStarTwoHeight);
        }
        paint.setAlpha((int) (starAlpha * 255));

        canvas.save();
        canvas.scale(sizePercent, sizePercent);
        canvas.drawBitmap(bitmap, srcRect, destRect, paint);
        canvas.restore();

    }

f.定时重会,实现动的效果

  Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if(isRuning){
                postInvalidate();
                handler.sendMessageDelayed(Message.obtain(),50);
            }
        }
    };
 public void startAnimationFloat(){
        isRuning=true;
        handler.sendMessage(Message.obtain());
    }

    public void stopAnimationFloat(){
        isRuning=false;

    }
    public void restartAnimationFloat(){
        startAnimationFloat();
    }

基本就这些,然后在activity布局里使用FloatView,设置不同运动方向轨迹即可;

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_float);
        int typeKey = getIntent().getIntExtra("type_key", 0);
        FloatView startBtn = (FloatView) findViewById(R.id.float_btn);
        startBtn.setFloatType(FloatView.FREE_POINT);
        if(typeKey==1){
            startBtn.setFloatType(FloatView.DEFAULT_TYPE);
        }else if(typeKey==2){
            startBtn.setFloatType(FloatView.FREE_POINT);
        }else if(typeKey==3){
            startBtn.setFloatType(FloatView.TOP);
        }else if(typeKey==4){
            startBtn.setFloatType(FloatView.BOTTOM);
        }else if(typeKey==5){
            startBtn.setFloatType(FloatView.LEFT);
        }else if(typeKey==6){
            startBtn.setFloatType(FloatView.RIGHT);
        }
        startBtn.startAnimationFloat();
    }

源码

时间: 2024-10-29 19:06:27

Android 的漂浮动画,下雪动画的相关文章

Android动画--属性动画Property Animation

简介 属性动画包含: ObjectAnimator 动画的执行类 ValueAnimator 动画的执行类 AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等. AnimatorInflater 用户加载属性动画的xml文件 ObjectAnimator 单一属性动画 缩放X轴:ScaleX ObjectAnimator().ofFloat(imageView,"ScaleY",1.0f,0.0f).setDuration(3000).start(); 缩

Android编程之Fragment使用动画造成Unknown animation name: objectAnimator异常

在为Fragment做切换动画,启动后遇到了一个异常: Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 截图如下: 我的代码如下: fragment = Fragment.instantiate(getActivity(), clz.getName()); fragment.setArguments(args); ft.setCustomAnimations(R.animator.frag

Android中的补间动画(tween)的简单使用

相对帧动画,补间动画(tween)可以这么理解:我们不必像帧动画一样指定动画的每一帧,只需定义一个动画的开始和结束关键帧,而中间变化的帧由系统帮我们计算. tween动画可以分为下面几种: AlphaAnimation(透明渐变动画): 示例:res/anim/alpha.xml <?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.andr

Android开发之自定义View-可动画展开收缩View的实现

有时候需要点击一个view可以动画展开和收缩折叠一个View这样的效果,这样就可以直接自定义View来实现. 本例中,采用继承FrameLayout来实现自定义的ExpandView.下面将详细介绍各个部分来实现该类以及如何使用该自定义视图. 效果图如下: 未展开效果: 正在向上折叠收缩中的效果: 已经展开效果: 自定义展开类:ExpandView的实现: package com.czm.customview; import android.content.Context; import and

Android的Activity屏幕切换动画(一)-左右滑动切换

这段时间一直在忙Android的项目,总算抽出点时间休息一下,准备把一些项目用到的Android经验分享一下. 在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,从Android2.0开始在Activity增加了一个方法: public void overridePendingTransition (int enterAnim, int exitAnim) 其中: enterAnim 定义A

Android图文详解属性动画

Android中的动画分为视图动画(View Animation).属性动画(Property Animation)以及Drawable动画.从Android 3.0(API Level 11)开始,Android开始支持属性动画,本文主要讲解如何使用属性动画.关于视图动画可以参见博文<Android四大视图动画图文详解>. 概述 视图动画局限比较大,如下所述: 视图动画只能使用在View上面. 视图动画并没有真正改变View相应的属性值,这导致了UI效果与实际View状态存在差异,并导致了一

动画--android图片点击放大动画,并遮挡旁边的控件

http://blog.csdn.net/s13488941815/article/details/40649823: 首先是点击放大可以使用android自带的缩放动画,因为要遮盖其他控件,就需要控件处在最上层,这里需要调用bringTofront方法@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {c

Android游戏开发研究帧动画实现

 1.动画的原则框架        帧的动画帧的动画顾名思义,画就是帧动画. 帧动画和我们小时候看的动画片的原理是一样的,在同样区域高速切换图片给人们呈现一种视觉的假象感觉像是在播放动画,事实上只是是N张图片在一帧一帧的切换罢了.对摄像头不清楚的请看p=992" rel="bookmark">Android研究之游戏开发摄像头更新        如图所看到的:人物行走动画的实现方式, 4帧行走动画在播放区域 一帧一帧向左切换播放 给人们一种播放动画的假象 .图片就动

android ScaleAnimation类:尺寸变化动画类

Android JDK为我们提供了4种动画效果,分别是: AlphaAnimation,RotateAnimation, ScaleAnimation, TranslateAnimation.今天我想讲解的是TranslateAnimation这个动画效果.也是本人在做一个移动图片的动画效果的项目时,遇到了一些问题.在网上查了很多资料,搞了好几天.终于明白怎么使用这个TranslateAnimation,在本文中记录下来,以便以后忘记了可以查阅. http://gundumw100.iteye.

android中xml设置Animation动画效果详解

在 android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation 画面转换动画. tweened animation 渐变动画有以下两种类型: 1.alpha 渐变透明度动画效果 2.scale 渐变尺寸伸缩动画效果 frame by frame animation 画面转换动画有以下两种类型: 1.translate 画面转换位置移动动画效果 2.rotate