核心内容:
1.绘制下雨场景的个体、雨点(直线)
2.让直线动起来
3.处理边界问题
4.构造雨点对象
5.雨点大小设置
6.速度设置和角度设置等
7.添加多个雨点
8.抽离可以在 XML 中影响的属性
9.在代码中解析样式属性并使用其控制雨点变化
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View; /**
* 基类
*/
public abstract class BaseView extends View {
private MyThread thread;
private boolean running = true; public BaseView(Context context, AttributeSet attrs) {
super(context, attrs);
} public BaseView(Context context) {
super(context);
} protected abstract void drawSub(Canvas canvas);
protected abstract void logic();
protected abstract void init(); class MyThread extends Thread {
@Override
public void run() {
init();
while (running) {
logic();
postInvalidate();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} @Override
protected final void onDraw(Canvas canvas) {
if (thread == null) {
thread = new MyThread();
thread.start();
} else {
drawSub(canvas);
}
} @Override
protected void onDetachedFromWindow() {
running = false;
super.onDetachedFromWindow();
} }

1)简单描述单个雨点的行为。

绘制下雨场景的个体,雨点(直线);

让直线动起来;

处理边界问题;

 <com.rain.RainView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff000000"
/>
   import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet; public class RainView extends BaseView {
private float startX;
private float startY;
private float stopX;
private float stopY;
private float sizeX;
private float sizeY;
private Paint paint; public RainView(Context context, AttributeSet attrs) {
super(context, attrs);
// 角度。
sizeX = 10;
sizeY = 30;
// 以下是 初始化直线的坐标。
startX = 100;
startY = 0;
// 改变 角度的直线。
stopX = startX + sizeX;
stopY = startY + sizeY; paint = new Paint();
// 把直线 设置成白色。
paint.setColor(0xffffffff);
} public RainView(Context context) {
super(context);
} @Override
protected void drawSub(Canvas canvas) {
// 绘制一条直线
canvas.drawLine(startX, startY, stopX, stopY, paint);
} @Override /* 让直线动起来 **/
protected void logic() { //倍率,通过倍率来改变速度。
float opt = 0.5f; startX += sizeX * opt;
stopX += sizeX * opt; startY += sizeY * opt;
stopY += sizeY * opt; // 当直线走出屏幕的时候,变为初始位置。
if (startY > getHeight()) {
startX = 100;
startY = 0;
stopX = startX + 10;
stopY = startY + 30;
}
} }

2)完善雨点行为和构造下雨场景。

构造雨点对象;

雨点大小设置;

速度设置;

角度设置等 添加多个雨点;

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.rain.RainView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff000000" />
</FrameLayout>
 public class RainView extends BaseView {
// 多个 “雨点” 对象。
private ArrayList<RainItem> list = new ArrayList<RainItem>();
private int rainNum = 80; // “雨点”个数。 public RainView(Context context, AttributeSet attrs) {
super(context, attrs);
} public RainView(Context context) {
super(context);
} @Override
protected void drawSub(Canvas canvas) {
for (RainItem item : list) {
item.draw(canvas);
}
} @Override
protected void logic() {
for (RainItem item : list) {
item.move();
}
} @Override
protected void init() {
for (int i = 0; i < rainNum; i++) {
RainItem item = new RainItem(getWidth(), getHeight());
list.add(item);
}
} }
 /**
* 抽象出一个 雨点 的类
*/
public class RainItem {
private int width;
private int height; private float startX;
private float startY;
private float stopX;
private float stopY;
private float sizeX;
private float sizeY;
private float opt; // 速率
private Paint paint;
private Random random; // 随机数 // 自定义“雨点”的 宽 和 高
public RainItem(int width, int height) {
this.width = width;
this.height = height;
init();
} private void init() {
random = new Random();
// 角度 "X和Y随机。
sizeX = 1 + random.nextInt(10);
sizeY = 10 + random.nextInt(20);
// "雨点"X和Y随机位置。
startX = random.nextInt(width);
startY = random.nextInt(height);
stopX = startX + sizeX;
stopY = startY + sizeY;
// 速率随机。
opt = 0.2f + random.nextFloat();
paint = new Paint(); paint.setColor(0xffffffff);
} public void draw(Canvas canvas) {
canvas.drawLine(startX, startY, stopX, stopY, paint);
} public void move() {
startX += sizeX * opt;
stopX += sizeX * opt; startY += sizeY * opt;
stopY += sizeY * opt; if (startY > height) {
init();
}
} }

3)在xml中定义可以控制下雨的属性。

抽离可以在xml中影响的属性;

在代码中解析样式属性并使用其控制雨点变化;

res/values/attrs.xml

 <?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RainView">
<!-- 雨点数量 -->
<attr name="rainNum" format="integer"/>
<!-- 雨点大小 -->
<attr name="size" format="integer"/>
<!-- 雨点颜色 -->
<attr name="rainColor" format="integer"/>
<!-- 雨点颜色随机 -->
<attr name="randColor" format="boolean"/>
</declare-styleable>
</resources>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:rain="http://schemas.android.com/apk/res/com.jikexueyuan.rain"

android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.rain.RainView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff000000"
rain:rainNum="50"
rain:size="20"
rain:rainColor="0xff00ff00"
rain:randColor="true"/>

</FrameLayout>
 public class RainView extends BaseView {
// 多个 “雨点” 对象。
private ArrayList<RainItem> list = new ArrayList<RainItem>();
// 以下4个值,均为默认值。
private int rainNum = 80; // “雨点”个数。
private int size;
private int rainColor;
private boolean randColor; public RainView(Context context, AttributeSet attrs) {
super(context, attrs); // 加载,解析 样式属性。res/values/attrs.xml
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.RainView); rainNum = ta.getInteger(R.styleable.RainView_rainNum, 80);
size = ta.getInteger(R.styleable.RainView_size, 20);
rainColor = ta.getInteger(R.styleable.RainView_rainColor, 0xffffffff);
randColor = ta.getBoolean(R.styleable.RainView_randColor, false);
ta.recycle();
} public RainView(Context context) {
super(context);
} @Override
protected void drawSub(Canvas canvas) {
for (RainItem item : list) {
item.draw(canvas);
}
} @Override
protected void logic() {
for (RainItem item : list) {
item.move();
}
} @Override
protected void init() {
for (int i = 0; i < rainNum; i++) {
RainItem item = new RainItem(getWidth(), getHeight(), size,
rainColor, randColor);
list.add(item);
}
} }
 /**
* 抽象出一个 雨点 的类
*/
public class RainItem { private int width;
private int height; private float startX;
private float startY;
private float stopX;
private float stopY;
private float sizeX;
private float sizeY;
private float opt; // 速率
private Paint paint;
private Random random; // 随机数 private int size = 20;
private int color;
// 随机 雨点颜色
private boolean randColor = false;; // 自定义“雨点”的 宽 和 高
public RainItem(int width, int height) {
this.width = width;
this.height = height;
init();
} public RainItem(int width, int height, int size) {
this.size = size;
this.width = width;
this.height = height;
init();
} public RainItem(int width, int height, int size, int color) {
this.color = color;
this.size = size;
this.width = width;
this.height = height;
init();
} public RainItem(int width, int height, int size, int color,
boolean randColor) {
this.randColor = randColor;
this.color = color;
this.size = size;
this.width = width;
this.height = height;
init();
} private void init() {
random = new Random();
// 角度 "X和Y随机。
sizeX = 1 + random.nextInt(size / 2);
sizeY = 10 + random.nextInt(size);
// "雨点"X和Y随机位置。
startX = random.nextInt(width);
startY = random.nextInt(height);
stopX = startX + sizeX;
stopY = startY + sizeY;
// 速率随机。
opt = 0.2f + random.nextFloat();
paint = new Paint();
if (randColor) {
// 颜色随机值。
int r = random.nextInt(256);
int g = random.nextInt(256);
int b = random.nextInt(256); paint.setARGB(255, r, g, b);
} else {
paint.setColor(color);
}
} public void draw(Canvas canvas) {
canvas.drawLine(startX, startY, stopX, stopY, paint);
} public void move() {
startX += sizeX * opt;
stopX += sizeX * opt; startY += sizeY * opt;
stopY += sizeY * opt; if (startY > height) {
init();
}
} }

DEMO下载路径:http://download.csdn.net/detail/androidsj/9279741

54、Android 粒子效果之雨(下雨的效果)的更多相关文章

  1. 6 cocos2dx粒子效果,类图关系,系统原生粒子和自己定义粒子效果,粒子编译器软件,爆炸粒子效果,烟花效果,火焰效果,流星效果,漩涡粒子效果,雪花效果,烟雾效果,太阳效果,下雨效果

     1 粒子 演示样例 2 类图关系 3 系统原生粒子 CCParticleSystem 全部粒子系统的父类 CCParticleSystemPoint. CCParticleSystemQuad ...

  2. 《推送开发全面盘点当前Android后台保活方案的真实运行效果》

        登录 立即注册 TCP/IP详解 资讯 动态 社区 技术精选 首页   即时通讯网›专项技术区›推送开发全面盘点当前Android后台保活方案的真实运行效果(截止2 ...   帖子 打赏 分 ...

  3. Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现

    Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现 暂时还未有时间开发这效果,所以先贴出来. 先贴一张效果图,这是一张手机截屏: 左上方的风景图:背景图片 右上方的人物图:前景图 ...

  4. 实现了在android实现左右滑动切换界面的效果

    这是实现了在android实现左右滑动切换界面的效果,该效果的源码下载,请到源码天堂下载吧,喜欢的朋友可以研究一下. 布局文件 <?xml version="1.0" enc ...

  5. android使用TextView实现跑马灯的效果(1)

    android使用TextView实现跑马灯的效果 1.activity_main.xml <?xml version="1.0" encoding="utf-8& ...

  6. Android - TabHost 与 Fragment 制作页面切换效果

    Android - TabHost 与 Fragment 制作页面切换效果 Android API 19 , API 23 三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义 ...

  7. 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

    本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者. 1.引言 对于IM应用和消息推送服务的开发者来说,在Androi ...

  8. android一个倾斜的TextView,适用于标签效果

    描述: android一个倾斜的TextView,适用于标签效果 应用截图: 使用说明: <com.haozhang.lib.SlantedTextView android:layout_wid ...

  9. Android设置常见控件点击效果

    一. Imageview的点击效果——图片稍微变暗突出点击效果 public class ClickImageView extends AppCompatImageView { public Clic ...

  10. android xml实现animation 4种动画效果

    animation有四种动画类型 分别为alpha(透明的渐变).rotate(旋转).scale(尺寸伸缩).translate(移动),二实现的分发有两种,一种是javaCode,另外一种是XML ...

随机推荐

  1. 理解Linux系统中的load average

    理解Linux系统中的load average(图文版) 博客分类: Linux linux load nagios  一.什么是load average? linux系统中的Load对当前CPU工作 ...

  2. esriControlsMousePointer常量

    控制鼠标指针选项. 不变 值 描述 esriPointerParentWindow -1 指针指定的父窗口或窗体. esriPointerDefault 0 默认指针,箭头一样. esriPointe ...

  3. http://blog.sina.com.cn/s/blog_6a01140c0100wimi.html

    http://blog.sina.com.cn/s/blog_6a01140c0100wimi.html

  4. 键盘enter按钮出发登陆事件

    $("#nameInput").focus();$(".txtUserName").keydown(function (event) { if (event.k ...

  5. 电子商务(电销)平台中商品模块(Product)数据库设计明细(转载)

    电子商务(电销)平台中商品模块(Product)数据库设计明细 以下是自己在电子商务系统设计中的数据库设计经验总结,而今发表出来一起分享,如有不当,欢迎跟帖讨论~ 商品表 (product)|-- 自 ...

  6. 使用 GROUP BY WITH ROLLUP 改善统计性能

    使用 GROUP BY 的 WITH ROLLUP 字句可以检索出更多的分组聚合信息,它不仅仅能像一般的 GROUP BY 语句那样检索出各组的聚合信息,还能检索出本组类的整体聚合信息. 下面我们的例 ...

  7. JUC组件扩展(二)-JAVA并行框架Fork/Join(一):简介和代码示例

    一.背景 虽然目前处理器核心数已经发展到很大数目,但是按任务并发处理并不能完全充分的利用处理器资源,因为一般的应用程序没有那么多的并发处理任务.基于这种现状,考虑把一个任务拆分成多个单元,每个单元分别 ...

  8. Spring Boot(七):spring boot测试介绍

    首先maven要引入spring-boot-starter-test这个包. 先看一段代码 @RunWith(SpringRunner.class) @SpringBootTest(webEnviro ...

  9. linux下的which

    which命令用来查找并打印可执行文件的绝对路径. 他会根据PATH环境变量定义的路径来依此查找可执行文件. 需要注意的是,指向可执行文件的链接文件在查找中会被忽略. 比如env命令: ll /usr ...

  10. python学习之io模块

    class io.BytesIO([initial_bytes]) 他是一个_io.BytesIO对象. 用这个类的实例可以操作内存缓冲区中的字节流. >>> s = 'hello' ...