核心内容:
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. iOS多线程的初步研究(一)-- NSThread

    对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...

  2. 每秒处理3百万请求的Web集群搭建-如何生成每秒百万级别的 HTTP 请求?

    本文是构建能够每秒处理 3 百万请求的高性能 Web 集群系列文章的第一篇.它记录了我使用负载生成器工具的一些经历,希望它能帮助每一个像我一样不得不使用这些工具的人节省时间. 负载生成器是一些生成用于 ...

  3. [转载]Scikit-learn介绍几种常用的特征选择方法

    #### [转载]原文地址:http://dataunion.org/14072.html 特征选择(排序)对于数据科学家.机器学习从业者来说非常重要.好的特征选择能够提升模型的性能,更能帮助我们理解 ...

  4. SSDB(网络LevelDB)-- 实际遇到的问题

    简介 SSDB -- 支持网络的LevelDB 站点:https://github.com/ideawu/ssdb 我实际使用了SSDB支持网络+持久化特性,完成了一个集群 1.句柄数 ulimit ...

  5. 阅读《Android 从入门到精通》(29)——四大布局

    LinearLayout 类方法 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQ ...

  6. kali2.0下配置Metasploit+postgresql链接

    工具/原料   kali2.0 方法/步骤     1.postgresql是本身没有启动的.所以需要启动. service postgresql start   2.通过命令进入配置 sudo -u ...

  7. intellij idea中修改代码生成的模板

    File -- Settings -- Editor -- Code Style -- File and Code Templates 主要是修改了注释 /** * ${DESCRIPTION} * ...

  8. php get_called_class()函数与get_class函数的区别

    get_class (): 获取当前调用方法的类名: get_called_class():获取静态绑定后的类名: 有例为证: class Foo{ public function test(){ v ...

  9. PHP的session存储对PHP运行环境的影响

    转于:http://hmw.iteye.com/blog/1704020 这个问题的引入是由于公司一个项目里需要使用单点登录的功能,为了方便起见,就使用redis来替换php默认的文件存储sessio ...

  10. GitHub的Fork 是什么意思

    现在有这样一种情形: 有一个叫做Joe的程序猿写了一个游戏程序,而你可能要去改进它.并且Joe将他的代码放在了GitHub仓库上. 下面是你要做的事情 fork并且更新GitHub仓库的图表演示 Fo ...