Android营造雪花和雨滴浪漫效果

本文在实现雪花效果的基础上,根据漫天飞舞雪花,实现下雨天场景的效果,使用eclipse android 版本,具体内容如下

雪花效果图:

具体代码:

1、漫天飞舞的雪花主要代码
SnowView

<span style="font-size:14px;">package com.ex</span>ample.snowflake.view; 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View; 

/**
 * 雪花视图, DELAY时间重绘, 绘制NUM_SNOWFLAKES个雪花
 */
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);
 } 

 @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];
 //mSnowFlakes所有的雪花都生成放到这里面
 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
 for (SnowFlake s : mSnowFlakes) {
  //然后进行绘制
  s.draw(canvas);
 }
 // 隔一段时间重绘一次, 动画效果
 getHandler().postDelayed(runnable, DELAY);
 } 

 // 重绘线程
 private Runnable runnable = new Runnable() {
 @Override
 public void run() {
  //自动刷新
  invalidate();
 }
 };
} 

SnowFlake

package com.example.snowflake.view; 

import com.example.snowflake.RandomGenerator; 

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point; 

/**
 * 雪花的类, 移动, 移出屏幕会重新设置位置.
 */
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) {
 //x水平方向,那么需要晃动,主要设置这个值就可以,现在取消晃动了
 //如果 mPosition.x不加上后面那个值,就不会晃动了
 double x = mPosition.x + (mIncrement * Math.cos(mAngle));
 //y是竖直方向,就是下落
 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 -5 && 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;
 }
}

2、实现下雨天效果代码
RainView

package com.example.raindrop.view; 

import com.example.raindrop.R; 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View; 

/**
 * 雨滴视图, DELAY时间重绘, 绘制NUM_SNOWFLAKES个雨滴
 */
public class RainView extends View { 

 private static final int NUM_SNOWFLAKES = 150; // 雨滴数量
 private static final int DELAY = 5; // 延迟
 private RainFlake[] mSnowFlakes; // 雨滴 

 public RainView(Context context) {
 super(context);
 } 

 public RainView(Context context, AttributeSet attrs) {
 super(context, attrs);
 } 

 public RainView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 } 

 @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(getResources().getColor(R.color.colorWater)); // 雨滴的颜色
 paint.setStyle(Paint.Style.FILL); // 填充;
 mSnowFlakes = new RainFlake[NUM_SNOWFLAKES];
 //mSnowFlakes所有的雨滴都生成放到这里面
 for (int i = 0; i < NUM_SNOWFLAKES; ++i) {
  mSnowFlakes[i] = RainFlake.create(width, height, paint);
 }
 } 

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 //for返回SnowFlake
 for (RainFlake s : mSnowFlakes) {
  //然后进行绘制
  s.draw(canvas);
 }
 // 隔一段时间重绘一次, 动画效果
 getHandler().postDelayed(runnable, DELAY);
 } 

 // 重绘线程
 private Runnable runnable = new Runnable() {
 @Override
 public void run() {
  //自动刷新
  invalidate();
 }
 };
}

RainFlake

package com.example.raindrop.view; 

import com.example.raindrop.RandomGenerator; 

import android.graphics.Canvas;
import android.graphics.Paint; 

/**
 * 雨滴的类, 移动, 移出屏幕会重新设置位置.
 */
public class RainFlake { 

 // 雨滴的移动速度
 private static final float INCREMENT_LOWER = 6f;
 private static final float INCREMENT_UPPER = 8f; 

 // 雨滴的大小
 private static final float FLAKE_SIZE_LOWER = 2f;
 private static final float FLAKE_SIZE_UPPER = 5f; 

 private final float mIncrement; // 雨滴的速度
 private final float mFlakeSize; // 雨滴的大小
 private final Paint mPaint; // 画笔 

 private Line mLine; // 雨滴 

 private RandomGenerator mRandom; 

 private RainFlake(RandomGenerator random,Line line, float increment, float flakeSize, Paint paint) {
 mRandom = random;
 mLine = line;
 mIncrement = increment;
 mFlakeSize = flakeSize;
 mPaint = paint;
 } 

 //生成雨滴
 public static RainFlake create(int width, int height, Paint paint) {
 RandomGenerator random = new RandomGenerator();
 int [] nline;
 nline = random.getLine(width, height); 

 Line line = new Line(nline[0], nline[1], nline[2], nline[3]);
 float increment = random.getRandom(INCREMENT_LOWER, INCREMENT_UPPER);
 float flakeSize = random.getRandom(FLAKE_SIZE_LOWER, FLAKE_SIZE_UPPER);
 return new RainFlake(random,line, increment, flakeSize, paint);
 } 

 // 绘制雨滴
 public void draw(Canvas canvas) {
 int width = canvas.getWidth();
 int height = canvas.getHeight();
 drawLine(canvas, width, height);
 } 

 /**
 * 改成线条,类似于雨滴效果
 * @param canvas
 * @param width
 * @param height
 */
 private void drawLine(Canvas canvas, int width, int height) {
 //设置线宽
 mPaint.setStrokeWidth(mFlakeSize);
 //y是竖直方向,就是下落
 double y1 = mLine.y1 + (mIncrement * Math.sin(1.5));
 double y2 = mLine.y2 + (mIncrement * Math.sin(1.5)); 

 //这个是设置雨滴位置,如果在很短时间内刷新一次,就是连起来的动画效果
 mLine.set(mLine.x1,(int) y1,mLine.x2 ,(int) y2); 

 if (!isInsideLine(height)) {
  resetLine(width,height);
 } 

 canvas.drawLine(mLine.x1, mLine.y1, mLine.x2, mLine.y2, mPaint);
 } 

 // 判断是否在其中
 private boolean isInsideLine(int height) {
 return mLine.y1 < height && mLine.y2 < height;
 } 

 // 重置雨滴
 private void resetLine(int width, int height) {
 int [] nline;
 nline = mRandom.getLine(width, height);
 mLine.x1 = nline[0];
 mLine.y1 = nline[1];
 mLine.x2 = nline[2];
 mLine.y2 = nline[3];
 } 

} 

雨滴效果图:

以上就是本文的全部内容,帮助大家轻松实现浪漫的雪花雨滴效果,大家可以把效果运用到自己的项目中,希望大家喜欢。

(0)

相关推荐

  • Android中View的炸裂特效实现方法详解

    本文实例讲述了Android中View的炸裂特效实现方法.分享给大家供大家参考,具体如下: 前几天微博上被一个很优秀的 Android 开源组件刷屏了 - ExplosionField,效果非常酷炫,有点类似 MIUI 卸载 APP 时的动画,先来感受一下. ExplosionField 不但效果很拉风,代码写得也相当好,让人忍不住要拿来好好读一下. 创建 ExplosionField ExplosionField 继承自 View,在 onDraw 方法中绘制动画特效,并且它提供了一个 att

  • Android实现粒子雨效果

    本文实例介绍了Android实现粒子雨效果的实现过程,分享给大家供大家参考,具体内容如下 先看看效果图: 具体实现方法: 1.baseview主要是设定雨滴要实现的动作,只是先设定,也就是抽象方法,在子类中实现其方法 2.Rainitems封装雨滴类 3.Rainitems对雨滴集合创建到面板中,显示出来,具体实现就是在这个类中 一.baseview封装类,子类继承后实现方法即可 public abstract class BaseView extends View { private cont

  • Android仿QQ聊天撒花特效 很真实

    先看看效果图吧 实现这样的效果,你要知道贝塞尔曲线,何谓贝塞尔曲线?先在这里打个问号 下面就直接写了 1.activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent

  • Android实现字母雨的效果

    首先来看效果: 一.实现原理 在实现过程中,主要考虑整个界面由若干个字母组成的子母线条组成,这样的话把固定数量的字母封装成一个字母线条,而每个字母又封装成一个对象,这样的话,就形成了如下组成效果: 字母对象-->字母线条对象-->界面效果 每个字母都应该知道自己的位置坐标,自己上面的字母.以及自己的透明度: class HackCode{ Point p = new Point();//每一个字母的坐标 int alpha = 255;//透明度值 默认255 String code = &q

  • Android营造雪花和雨滴浪漫效果

    本文在实现雪花效果的基础上,根据漫天飞舞雪花,实现下雨天场景的效果,使用eclipse android 版本,具体内容如下 雪花效果图: 具体代码: 1.漫天飞舞的雪花主要代码 SnowView <span style="font-size:14px;">package com.ex</span>ample.snowflake.view; import android.content.Context; import android.graphics.Canvas

  • Android编程实现自定义渐变颜色效果详解

    本文实例讲述了Android编程实现自定义渐变颜色效果.分享给大家供大家参考,具体如下: 你是否已经厌恶了纯色的背景呢?那好,Android提供给程序员自定义渐变颜色的接口,让我们的界面炫起来吧. xml定义渐变颜色 首先,你在drawable目录下写一个xml,代码如下 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.

  • Android ListView的Item点击效果的定制

    Android ListView的Item点击效果的定制           前言:           对于listview Android开发的朋友都知道用的很多,网上关于Android ListView的Item点击特效的文章很多,我自己也看了不少关于listview的文章,这里就记录下不错的文章,大家可以参考下, 在之前弄这个效果说真的很不明智,我是在Item的布局文件加个selector的xml文件来实现ListView的Item点击效果.. 这个算是我自己记录以后该如何使用的另一种方

  • Android实现广告图片轮播效果

    本文实例介绍了Android广告轮播图效果实现方法,分享给大家供大家参考,具体内容如下 首先看下一下布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:

  • Android实现RecyclerView下拉刷新效果

    本文为大家分享了Android实现RecyclerView下拉刷新效果的具体代码,供大家参考,具体内容如下 思路 RealPullRefreshView继承了一个LinearLayout 里面放置了一个刷新头布局,将其margin_top设置为负的刷新头的高度的 再添加一个RecyclerView 触摸事件分发机制,当在特定条件下让RealPullRefreshView拦截触摸事件,否则的话,不拦截,让RecyclerView自己去处理触摸事件 在手指下拉时,定义好不同的状态STATE,在不同状

  • Android游戏开发学习②焰火绽放效果实现方法

    本文实例讲述了Android游戏开发学习②焰火绽放效果实现方法.分享给大家供大家参考.具体如下: 本节介绍在游戏开发中常用到的数学物理应用--粒子系统.粒子系统与上一节的小球有类似的地方,都是通过数学方法和物理公式模拟客观世界中的物体的运动轨迹.不同的是小球更强调个体运动,而焰火粒子等粒子系统更注重整体感觉. 一.焰火粒子效果 1.粒子对象类Particle类和粒子集合类ParticleSet类 每个粒子都为一个Particle类的对象,程序中产生的所有Particle对象都由一个Particl

  • Android利用CountDownTimer实现验证码倒计时效果实例

    前言 等待总是让人感到焦急和厌烦的,特别是看不到进展的等待.所以为了不让用户痴痴地等,我们在进行某些耗时操作时,一般都要设计一个进度条或者倒计时器,让进度可视化,告诉用户"等待之后更精彩".在使用短信验证码注册或者登录App就可以看到这样的设计:点击"发送验证码"的按钮之后,按钮上就会出现倒计时(一般为60秒),倒计时结束之后,按钮的文字就会变成"重新发送". 在Android中要实现这样的效果可以使用Handler发送消息,但其实还有一个已经封

  • Android编程实现仿iphone抖动效果的方法(附源码)

    本文实例讲述了Android编程实现仿iphone抖动效果的方法.分享给大家供大家参考,具体如下: 布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" and

  • Android仿斗鱼直播的弹幕效果

    记得之前有位朋友在我的公众号里问过我,像直播的那种弹幕功能该如何实现?如今直播行业确实是非常火爆啊,大大小小的公司都要涉足一下直播的领域,用斗鱼的话来讲,现在就是千播之战.而弹幕则无疑是直播功能当中最为重要的一个功能之一,那么今天,我就带着大家一起来实现一个简单的Android端弹幕效果. 分析 首先我们来看一下斗鱼上的弹幕效果,如下图所示: 这是一个Dota2游戏直播的界面,我们可以看到,在游戏界面的上方有很多的弹幕,看直播的观众们就是在这里进行讨论的. 那么这样的一个界面该如何实现呢?其实并

  • Android开发设置RadioButton点击效果的方法

    本文实例讲述了Android开发设置RadioButton点击效果的方法.分享给大家供大家参考,具体如下: 在安卓开发中用到底部菜单栏 需要用到RadioButton这个组件 实际应用的过程中,需要对按钮进行点击,为了让用户知道是否点击可这个按钮,可以设置点击后 ,该按钮的颜色或者背景发生变化. layout中这部分的代码为: <RadioButton android:id="@+id/radio_button0" android:layout_height="fill

随机推荐