Android雪花下落效果
来源:互联网 发布:美工数字字体图片 编辑:程序博客网 时间:2024/04/30 14:37
必须先上图:
图片看不到可以上GitHub看Demo:https://github.com/OptimusPrimeRen/SnowflakesView
再上代码:
(注释还算多,不算太难,就不详述过程了)
public class SnowflakesView extends View { private FallSnowThread mFallSnowThread; private Snow[] mSnows; //雪花对象集合 private Drawable mSnowFlowerDrawable; private int mSnowFlowerHeight; //雪花原始高度 private int mSnowViewWidth; //整个view的高度 private int mSnowViewHeight; //整个view的宽度 private Random mRandom; //随机数发生器,发生雪花缩放大小、雪花初始x轴坐标 private float mFallSpeed; //雪花下降速度 private int mSnowCount; //雪花总数量 private enum FallSnowState {START, PAUSE, RUNNING, STOP} private FallSnowState mFallSnowState; public SnowflakesView(Context context) { this(context, null); } public SnowflakesView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SnowflakesView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(context, attrs, defStyleAttr); initVariable(); } private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SnowflakesView); //下落速度 mFallSpeed = typedArray.getFloat(R.styleable.SnowflakesView_fallSpeed, (float) 0.1); //下落雪花个数 mSnowCount = typedArray.getInteger(R.styleable.SnowflakesView_snowCount, 10); typedArray.recycle(); judgeAttrIsReasonable(); } //判断自定义参数是否合法 private void judgeAttrIsReasonable() { if (mSnowCount <= 0) { throw new RuntimeException("snow count must > 0"); } if (mFallSpeed <= 0) { throw new RuntimeException("fall snow speed must > 0"); } } public void initVariable() { mRandom = new Random(); //此处使用Drawable对象而不是Bitmap,原因是:Drawable提供setAlpha方法,而Bitmap没有。当然,也可以通过设置canvas的alpha,不过测试表示效率较低。 mSnowFlowerDrawable = getResources().getDrawable(R.drawable.image_cpu_cooler_snow); //获取图片原始高度,用于之后计算 mSnowFlowerHeight = mSnowFlowerDrawable.getIntrinsicHeight(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); //整个view的宽高 mSnowViewWidth = r - l; mSnowViewHeight = b - t; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mSnows == null) { return; } for (Snow snow : mSnows) { canvas.save(); //通过设置Drawable边界,从而Drawable会自动对其中图片进行缩放,注意:这里的四个参数,分别是图片在整个view(canvas)中的顶点 mSnowFlowerDrawable.setBounds((int) snow.mX, (int) snow.mY, (int) (snow.mX + mSnowFlowerHeight * snow.mScale), (int) (snow.mY + mSnowFlowerHeight * snow.mScale)); mSnowFlowerDrawable.setAlpha(snow.mAlpha); mSnowFlowerDrawable.draw(canvas); canvas.restore(); } } //caculate all snow next attrs , include position,size etc. 计算所有雪花的相关参数 包括位置 大小等 private void calculateSnowsNextAttr() { for (Snow snow : mSnows) { snow.calculateNextAttr(); } } //单个雪花对象,用于保存雪花的状态 private class Snow { public float mScale; public int mAlpha; //alpha public float mX; public float mY; public Snow() { init(); } private void init() { mAlpha = mRandom.nextInt(200) + 55; //55~255 alpha mScale = (mRandom.nextFloat() + 1) / 2; //0.5~1.5 scale mX = mRandom.nextInt(mSnowViewWidth); mY = -mSnowFlowerHeight; } //caculate the snow's next attrs , include position,size etc. 计算下一个雪花的相关参数 包括位置 大小等 public void calculateNextAttr() { //很简单,当监测到雪花落到view底部时,重新计算初始值。 if (mY > mSnowViewHeight / mScale) { init(); } else { //没到底部,以一定速率下降,这里乘以mScale使得越大的落得越快 mY = mY + mScale * mSnowFlowerHeight * mFallSpeed; } } } //开始下雪 public void startSnow() { mFallSnowState = FallSnowState.START; if (mFallSnowThread == null) { mFallSnowThread = new FallSnowThread(); } mSnows = new Snow[mSnowCount]; for (int i = 0; i < mSnows.length; i++) { mSnows[i] = new Snow(); } if (mFallSnowState == FallSnowState.START) { mFallSnowThread.start(); mFallSnowState = FallSnowState.RUNNING; } } //暂停下雪 public void pauseSnow() { if (mFallSnowState == FallSnowState.RUNNING) { mFallSnowState = FallSnowState.PAUSE; } } //继续下雪 public void resumeSnow() { if (mFallSnowState == FallSnowState.PAUSE) { mFallSnowState = FallSnowState.RUNNING; } } //停止下雪 public void stopSnow() { mFallSnowState = FallSnowState.STOP; } private class FallSnowThread extends Thread { @Override public void run() { while (true) { switch (mFallSnowState) { case RUNNING: calculateSnowsNextAttr(); postInvalidate(); try { //大约30帧的动画速度,不会太多冗余计算与刷新 //当然,如果4.0以上,可以使用valueAnimator,不需新开线程,损耗较小。 //也可以使用HandlerThread,Timer等,不过本质上都是线程。 Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } break; case PAUSE: try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } break; case STOP: Thread.interrupted(); break; default: break; } } } }}
使用方法:
1.布局文件
<com.opr.snowflakesview.SnowflakesView android:id="@+id/snowflakes" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_blue_light" app:fallSpeed="0.1" app:snowCount="50"/>
2.代码中:
AppCenterIconView mAppCenterIconView; mAppCenterIconView = (AppCenterIconView) findViewById(R.id.rl_app_center_icon); mAppCenterIconView.startAppBoxAnim();
1 0
- Android雪花下落效果
- Android 给指定RelativeLayout添加雪花下落效果
- Android 雪花飘落效果
- android雪花效果
- Android 水滴下落效果View
- Android 实现雪花飞舞效果
- 雪花下落+雪花颜色随机+形状随机
- 雪花效果
- android实现漫天雪花&下雨效果
- Android动画-实现雪花飞舞动画效果
- android 实现漫天飞舞雪花以及下雨天的效果
- Android自定义View——从零开始实现雪花飘落效果
- AS3雪花飘落效果
- 雪花飘落效果
- IOS 雪花飘落效果
- ActionScript 实现雪花效果
- 雪花飘落效果
- 雪花效果前台
- JAVA中子类是否可以可以继承、重写父类的静态方法--总结
- 欢迎使用CSDN-markdown编辑器
- activity——按back键会让当前activity消亡
- 1801: [Ahoi2009]chess 中国象棋
- Android Studio中使用Lambda表达式
- Android雪花下落效果
- centos6 mysql Access denied for user 'root'@'211.139.247.54' (using password: YES)
- STL string常用函数
- eclipse导入后将普通项目变为java项目
- 观察进程的内存占用情况
- IO流——转换流之BufferedWriter
- SPFA 模板
- 安卓手机你以为你删除了文件短信,通讯录你就百事无忧了?
- web.xml配置文件