Android 炫舞漫天飞雪效果图

今天周日,不适合出门,太冷了,俗说:一九二九不出手,三九四九零来走。。

我们的应用也可以有一些冬天的效果, 教大家做一个下雪的动画效果, 参考.

主要

(1) 隐藏status bar, 全屏显示图片.
(2) 绘制多个点, 实现移动效果.
(3) 回收点, 避免重复创建.

我喜欢用注释说话, 请大家多关注代码中的注释.

Github下载地址

1. 雪花类

雪花的属性包含: 随机量, 位置, 增量, 大小, 角度, 画笔.

绘画的过程中, 使用角度会移动点的位置, 每次速率都不同.

当雪花移出屏幕时, 会重新使用, 在屏幕的顶端重新落下.

算法参考.

/**
* 雪花的类, 移动, 移出屏幕会重新设置位置.
* <p/>
* Created by wangchenlong on 16/1/24.
*/
public class SnowFlake {
// 雪花的角度
private static final float ANGE_RANGE = 0.1f; // 角度范围
private static final float HALF_ANGLE_RANGE = ANGE_RANGE / 2f; // 一般的角度
private static final float HALF_PI = (float) Math.PI / 2f; // 半PI
private static final float ANGLE_SEED = 25f; // 角度随机种子
private static final float ANGLE_DIVISOR = 10000f; // 角度的分母
// 雪花的移动速度
private static final float INCREMENT_LOWER = 2f;
private static final float INCREMENT_UPPER = 4f;
// 雪花的大小
private static final float FLAKE_SIZE_LOWER = 7f;
private static final float FLAKE_SIZE_UPPER = 20f;
private final RandomGenerator mRandom; // 随机控制器
private final Point mPosition; // 雪花位置
private float mAngle; // 角度
private final float mIncrement; // 雪花的速度
private final float mFlakeSize; // 雪花的大小
private final Paint mPaint; // 画笔
private SnowFlake(RandomGenerator random, Point position, float angle, float increment, float flakeSize, Paint paint) {
mRandom = random;
mPosition = position;
mIncrement = increment;
mFlakeSize = flakeSize;
mPaint = paint;
mAngle = angle;
}
public static SnowFlake create(int width, int height, Paint paint) {
RandomGenerator random = new RandomGenerator();
int x = random.getRandom(width);
int y = random.getRandom(height);
Point position = new Point(x, y);
float angle = random.getRandom(ANGLE_SEED) / ANGLE_SEED * ANGE_RANGE + HALF_PI - HALF_ANGLE_RANGE;
float increment = random.getRandom(INCREMENT_LOWER, INCREMENT_UPPER);
float flakeSize = random.getRandom(FLAKE_SIZE_LOWER, FLAKE_SIZE_UPPER);
return new SnowFlake(random, position, angle, increment, flakeSize, paint);
}
// 绘制雪花
public void draw(Canvas canvas) {
int width = canvas.getWidth();
int height = canvas.getHeight();
move(width, height);
canvas.drawCircle(mPosition.x, mPosition.y, mFlakeSize, mPaint);
}
// 移动雪花
private void move(int width, int height) {
double x = mPosition.x + (mIncrement * Math.cos(mAngle));
double y = mPosition.y + (mIncrement * Math.sin(mAngle));
mAngle += mRandom.getRandom(-ANGLE_SEED, ANGLE_SEED) / ANGLE_DIVISOR; // 随机晃动
mPosition.set((int) x, (int) y);
// 移除屏幕, 重新开始
if (!isInside(width, height)) {
reset(width);
}
}
// 判断是否在其中
private boolean isInside(int width, int height) {
int x = mPosition.x;
int y = mPosition.y;
return x >= -mFlakeSize - 1 && x + mFlakeSize <= width && y >= -mFlakeSize - 1 && y - mFlakeSize < height;
}
// 重置雪花
private void reset(int width) {
mPosition.x = mRandom.getRandom(width);
mPosition.y = (int) (-mFlakeSize - 1); // 最上面
mAngle = mRandom.getRandom(ANGLE_SEED) / ANGLE_SEED * ANGE_RANGE + HALF_PI - HALF_ANGLE_RANGE;
}
}

随机数生成器, 包含区间随机和上界随机.
/**
* 随机生成器
* <p/>
* Created by wangchenlong on 16/1/24.
*/
public class RandomGenerator {
private static final Random RANDOM = new Random();
// 区间随机
public float getRandom(float lower, float upper) {
float min = Math.min(lower, upper);
float max = Math.max(lower, upper);
return getRandom(max - min) + min;
}
// 上界随机
public float getRandom(float upper) {
return RANDOM.nextFloat() * upper;
}
// 上界随机
public int getRandom(int upper) {
return RANDOM.nextInt(upper);
}
}

2. 雪花视图

雪花视图, DELAY时间重绘, 绘制NUM_SNOWFLAKES个雪花.
初始化在onSizeChanged中进行, 绘制在onDraw中进行.

/**
* 雪花视图, DELAY时间重绘, 绘制NUM_SNOWFLAKES个雪花
* <p/>
* Created by wangchenlong on 16/1/24.
*/
public class SnowView extends View {
private static final int NUM_SNOWFLAKES = 150; // 雪花数量
private static final int DELAY = 5; // 延迟
private SnowFlake[] mSnowFlakes; // 雪花
public SnowView(Context context) {
super(context);
}
public SnowView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SnowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public SnowView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w != oldw || h != oldh) {
initSnow(w, h);
}
}
private void initSnow(int width, int height) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 抗锯齿
paint.setColor(Color.WHITE); // 白色雪花
paint.setStyle(Paint.Style.FILL); // 填充;
mSnowFlakes = new SnowFlake[NUM_SNOWFLAKES];
for (int i = 0; i < NUM_SNOWFLAKES; ++i) {
mSnowFlakes[i] = SnowFlake.create(width, height, paint);
}
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (SnowFlake s : mSnowFlakes) {
s.draw(canvas);
}
// 隔一段时间重绘一次, 动画效果
getHandler().postDelayed(runnable, DELAY);
}
// 重绘线程
private Runnable runnable = new Runnable() {
@Override
public void run() {
invalidate();
}
};
}

使用getHandler().postDelayed(runnable, DELAY);刷新页面.

3. 全屏布局

全屏布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CollapsingToolbarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:scaleType="centerCrop"
android:src="@drawable/christmas"/>
<me.chunyu.spike.wcl_snowfall_demo.views.SnowView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</android.support.design.widget.CollapsingToolbarLayout>

status bar默认是不会被透明化的, 需要使用CollapsingToolbarLayout,
替换status bar的样式, 否则会留有一定高度, 即使透明也不会填充.
样式

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme.NoStatusBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
(0)

相关推荐

  • js点亮星星评分并获取参数的js代码

    用到的图片如下: 在线演示地址:http://demo.jb51.net/js/2014/jsxxdf/demo2.html 完整代码: 网页特效 添加行为的星星评级效果 我们欢迎您. 我们,站长必备的高质量网页特效和广告代码. 服务 default level 1 2 3 4 5 价格 default level 1 2 3 4 5 质量 default level 1 2 3 4 5 0){ a_obj[0].onclick=function(){ return give_value(thi

  • js实现漫天星星效果

    本文实例为大家分享了漫天小星星效果的实现代码,供大家参考,具体内容如下 效果图: 实现代码: <html onclick="init(event)"> <head> <title> new document </title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <script ty

  • jquery实现漫天雪花飞舞的圣诞祝福雪花效果代码分享

    这是一款基于jquery实现的漫天雪花飞舞的圣诞祝福雪花效果代码,雪花的大小可以进行切换,用户还可以更改背景图片,是一款非常实用的幻灯片特效源码. 漫天雪花飞舞的jquery圣诞祝福雪花效果,集中不同的效果可以点击选择,请欣赏. 效果演示 源码下载(浏览器中如果不能正常运行,可以尝试切换浏览模式或者选择直接下载) 为大家分享的漫天雪花飞舞的jquery圣诞祝福雪花效果代码如下 <!DOCTYPE html> <html> <head> <script type=&

  • javascript+css好多网站用的选星星实现打分功能的函数

    函数有两个参数,功能如下: obj:  img标签组的父容器,类型为DOM对象: oEvent: event对象.这个函数的优点是html代码可以很简洁,使用图片也可以很少,只需要两张图片.事件句柄只需要写在img的父容器上即可.演示用的图片我用的是绝对地址,各位在使用的时候改成网站的相对地址就可以了.当我们点击的时候,我用的是个alert事件.事实上,我们会在这个地方用个ajax方法,把相关的参数传到服务器端.只要把alert(this._num+1)写成sendAjax(this._num+

  • js实现星星打分效果的方法

    本文实例讲述了js实现星星打分效果的方法.分享给大家供大家参考.具体分析如下: 很多网站都有如下图这样的星星打分效果,今天就看下用js怎么实现打分效果. 效果详解 1. 鼠标移上的时候星星点亮,下面的文字显示.鼠标移出的时候星星为灰,下面文字不显示. 2. 鼠标移到某个星星上,它之前的所有星星都会亮. 3. 鼠标移到某个星星上并点击,会显示打分结果.   代码如下 <!doctype html> <html> <head> <meta charset="

  • javascript实现随机显示星星特效

    本文实例讲解了javascript实现随机显示星星特效的详细代码,具体内容如下 (1)网页背景是黑的  (2)星星随机大小:min=15,max=80  (3)星星的坐标是随机的:               x_left=0,x_right=(浏览器宽-星星宽)               y_top=0,y_bottom=? (4)单击某个星星,星星消失 (5)网页加载完成,开始显示星星 (6)定时器:每隔一个周期,插入一个星星 <html> <head> <meta h

  • js实现飞入星星特效代码

    本文实例讲述了js实现飞入星星特效代码,分享给大家供大家参考. 具体实现代码如下: 复制代码 代码如下: <html> <head> <title>星空极速飞入效果</title> <style type="text/css"> <!-- body { background-color: #000066; } --> </style> </head> <body> <scr

  • Android仿开心消消乐大树星星无限循环效果

    啥都不说先上效果图,这个是我项目里的效果: 下面的是我抽取出来的 demo 适配啥的我基本上都做好了没做其他的 ok 下面 说一下思路把 首先 说一下原理 我是使用bitmap 创建两张图 一开始的时候 一张在下面记为1号 一张在上面 记为2号 当手指向下滑动时 判断 1号 的起点位置 是否完全超出屏幕 如果超出屏幕的话 那么将2号变为下面 1号变为上面 (移动1号的Y坐标) 大体思路 是这样. 里面还有许多判断 比如 是否能向下滑动 起点位置, 星星的判定 哎呀 好烦 说的东西太多啦 来张我的

  • js星星评分效果

    html如下: <div class="starts"> <ul id="pingStar"> <li rel="1" title="特别差,给1分"></li> <li rel="2" title="很差,给2分"></li> <li rel="3" title="一般般,给3分

  • JS实现星星评分功能实例代码(两种方法)

    一.方法1 1.用到图片 2.结构和样式 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> ul { padding-left: 0; overflow: hidden; } ul li { float: left; list-style: no

随机推荐