核心内容:
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. TX2 ROS IDE开发环境配置

    参考资料: http://www.mamicode.com/info-detail-1663827.html    基于Qt搭建ROS开发环境 https://blog.csdn.net/sbtxg/ ...

  2. Spring Boot(二)Application events and listeners

    一.自定义监听器: 1.创建: META-INF/spring.factories 2.添加: org.springframework.context.ApplicationListener=com. ...

  3. 自闭合标签-主动闭合标签-meta-link标签

    <!DOCTYPE html><!--规定标准的html--><!--一个页在只有一对html标签--><!--标签的属性 指定英文--><htm ...

  4. Android之常用功能代码

    透明导航栏 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getWindow().addFlags(WindowManage ...

  5. 转在Python中实现PageFactory模式

    转自: http://www.cnblogs.com/fnng/p/5092383.html 关于 PageFactory 的概念主要是Java中内置了PageFactory类. import org ...

  6. 把一个base64编码的图片绘制到canvas (canvas的图片在转成dataurl)

    把一个base64编码的图片绘制到canvas 需要引入jquery. <canvas id="myCanvas" width="800" height= ...

  7. unity, access standard shared emission by script

    unity 5.1.1f1 personal 用下面方法在脚本中设置standard shader的emssion: gameObject.GetComponent<MeshRenderer&g ...

  8. Selenium自動化測試(Python+VS2013)-基礎篇-環境安裝

    Python+VS2013環境安裝 http://www.cnblogs.com/aehyok/p/3986168.html PTVS: http://microsoft.github.io/PTVS ...

  9. 如何借助Monit搭建服务器监控系统?(1)

    许多Linux管理员依赖一种集中式远程监控系统(比如Nagios或Cacti),检查网络基础设施的健康状况.虽然集中式监控系统为管理员在处理许多主机和设备时简化了工作,但专用的监控设备显然成了单一故障 ...

  10. UVALive 7712 Confusing Manuscript 字典树 查询与s的编辑距离为1的字符串数量

    /** 题目:UVALive 7712 Confusing Manuscript 链接:https://vjudge.net/problem/UVALive-7712 题意:给定n个不同的字符串,f( ...