(本博客为原创:http://www.cnblogs.com/linguanh/)

目录:

  效果展示

  感想

  代码拆解

  开源地址

效果展示

  有没有兴趣继续看下去,直接看下"颜值"是第一步了。依次对应:下雨,飘雪,红包雨,碰撞球

   

  上面是图片,这里再发个视频链接:http://pan.baidu.com/s/1miyPn76

感想

  16年总算过去了,跟各位猿友有说句祝福吧,新的一年少加点班,身体健康,钱能赚多少就尽量赚。

  之前看博客园,很多发纯感想的,都被推荐了好几天,说实话,我几乎一拉到底,就看有没有点↓的。

  公司放假时间是在23号,也就明天了,大四实习到现在,一直很忙,这段时间也是我在编程层面上学到了比较多东西的阶段,上面的自定义View是Android的,完成它们是在实习上班期间挤出时间做的,最初的初衷是想把第四个碰撞球的效果加入到毕设里面,现在总算是实现了,过程遇到很多问题,球体的碰撞处理比想象中麻烦很多,前三个比较简单,也是微信,QQ的下表情原理吧,我猜应该是。。。

  毕设最终也会开源,还请大家留意我 GitHbub,这将会是一个集合非第三方IM和仿朋友圈+golang制作服务端等等知识的社交APP。

代码拆解

  如果你仔细看了上面的四张效果图,你会发现,前三张是没碰撞效果处理的,而第四张是具备的。这也是我要区分实现的效果,目的是为了表明,不仅可以不碰撞还可以选择碰。

  同时,飘雪和红包雨,事实也仅仅是图片的不同,这就对了。你只需要修改图片就能实现完全自定义,爱下什么下什么。

  言归正传,整体使用了 适配器设计模式。代码是很简练易懂的,可以看看我的目录结构。

  

  基类是一个暴露绘制和逻辑抽象方法的View子类,所有自定义View需要继承它。子类只需要关注自己要绘制什么,以及我要绘制的东西怎么去不断地改变,逻辑改变设计在一个 Thread 线程里面,采用 postInvalidate 通知 UI 刷新。

 /**
* Created by LinGuanHong on 2017/1/15.
*
* My GitHub : https://github.com/af913337456/
*
* My Blog : http://www.cnblogs.com/linguanh/
*
*/ public abstract class BaseView extends View { protected String TAG = "zzzzz";
private static final int sleepTime = 30;
private RefreshThread refreshThread = null; public BaseView(Context context) {
super(context);
} public BaseView(Context context, AttributeSet attrs) {
super(context, attrs);
} public abstract void drawSub(Canvas canvas); public abstract void baseInit(int width,int height); public abstract void logic(); @Override
protected final void onDraw(Canvas canvas) {
if(refreshThread == null){
refreshThread = new RefreshThread();
refreshThread.start();
}else{
drawSub(canvas);
}
} @Override
protected void onDetachedFromWindow() {
running = false;
super.onDetachedFromWindow();
} private boolean running = true;
private class RefreshThread extends Thread{ @Override
public void run() {
baseInit(getWidth(),getHeight());
while (running){
try{
logic();
postInvalidate();
Thread.sleep(sleepTime);
}catch (Exception e){
Log.d(TAG,e.toString());
}
}
}
}
}

   BaseView 已经是一个可以直接继承的父类了,如果仅仅只是绘制一些比较简单逻辑的自定义View,继承它足以,但是要实现上述的效果,还需要添加多一个抽象类,无论是雨景还是雪景,它们都是个体的集合,也就是说,我们需要一个"景"的抽象。

  ShowView 是一个具备泛型的抽象类,它是景色的制作者,至于是什么景,由你来决定,也就是泛型的传入。例如,我要制造雨景,那么我就传入雨点,雪景就是雪块

 /**
* Created by LinGuanHong on 2017/1/15.
*
* My GitHub : https://github.com/af913337456/
*
* My Blog : http://www.cnblogs.com/linguanh/
*
*/ public abstract class ShowView<T extends BaseItem> extends BaseView { protected List<T> itemList = new ArrayList<>();
protected int size = 1; public ShowView(Context context) {
super(context);
} /** 子类实现布局必须要重写这个构造方法 */
public ShowView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
public void drawSub(Canvas canvas) {
for(T t:itemList){
t.draw(canvas);
}
} @Override
public void logic() {
beforeLogicLoop();
for(T t:itemList){
t.move();
}
} public abstract void beforeLogicLoop();
public abstract T getItem(int width, int height,Resources resources);
public abstract int getCount(); @Override
public void baseInit(int width, int height) {
size = getCount();
Resources resources = getResources();
for(int i = 0; i< size; i++){
itemList.add(getItem(width,height,resources));
}
} }

  由于我们的景色里面的个体可能是各种各样,那么为了使他们都能具备一些公共的属性,需要再抽象一个基础的个体类,共不同的景色个体继承。

 /**
* Created by LinGuanHong on 2017/1/15.
*
* My GitHub : https://github.com/af913337456/
*
* My Blog : http://www.cnblogs.com/linguanh/
*
* 公共的属性和行为
*
*/ public abstract class BaseItem { protected int width,height; /** 景内宽高 */
protected Resources resources; public BaseItem(int width,int height,Resources resources){
this.width = width;
this.height = height;
this.resources = resources;
} public abstract void draw(Canvas canvas); /** 显示 */
public abstract void move(); /** 运动 */ }

  OK,到这里基础的类都搞定了,为什么说是适配器模式呢,其实 BaseItem 就是 ViewHolder,ShowView 是 BaseAdapter,下面放下雨的Item 类和雨景。

  注意注释,代码很简练易懂!

 /**
* Created by LinGuanHong on 2017/1/15.
*
* 造雨,造多少个,160个,具体是什么雨,交给 item 实现
*
*/ public class RainView extends ShowView<RainItem> { public RainView(Context context) {
super(context);
} public RainView(Context context, AttributeSet attrs) {
super(context, attrs);
} @Override
public void beforeLogicLoop() { } @Override
public RainItem getItem(int width, int height, Resources resources) {
return new RainItem(width,height,resources); /** 要造的雨,是什么雨就在这里传入 */
} @Override
public int getCount() { /** 要制作的雨数目 */
return 160;
}
}

  我要制作的雨,随机数可以自定义。

 /**
* Created by LinGuanHong on 2017/1/15.
*/ public class RainItem extends BaseItem { private float opt;
private int sizeX,sizeY; /** 充当角度 */
private int startX,startY,stopX,stopY;
private Paint paint;
private Random random; public RainItem(int width, int height, Resources resources) {
super(width,height,resources);
init();
loopInit();
} @Override
public void move() {
startX += sizeX * opt;
stopX += sizeX * opt; startY += sizeY * opt;
stopY += sizeY * opt;
if(startY > height){
loopInit();
}
} @Override
public void draw(Canvas canvas) {
Log.d("zzzzz","drawView "+startX+" "+startY+" "+stopX+" "+stopY);
canvas.drawLine(startX,startY,stopX,stopY,paint);
} private void loopInit(){
sizeX = 1 + random.nextInt(10);
sizeY = 10 + random.nextInt(20); startX = random.nextInt(width );
startY = random.nextInt(height); opt = 0.2f + random.nextFloat(); stopX = startX + sizeX;
stopY = startY + sizeY;
} private void init(){
paint = new Paint(Paint.ANTI_ALIAS_FLAG); /** 抗锯齿 */
paint.setColor(0xffffffff); /** a,r,g,b 255,255,255,255 */ random = new Random();
} }

  到这里总结一下,如果你想实现自己的自定义View,不妨直接继承 BaseView,然后写你自己的 Item,就可以了。

开源地址

  我的:https://github.com/af913337456/XView

  

2017了,回家前 "年末" 分享:下雨,飘雪,红包雨,碰撞球,自定义View的更多相关文章

  1. 2017年排名前15的数据科学python库

    2017年排名前15的数据科学python库 2017-05-22 Python程序员 Python程序员 Python程序员 微信号 pythonbuluo 功能介绍 最专业的Python社区,有每 ...

  2. Android自定义View前传-View的三大流程-Measure

    Android自定义View前传-View的三大流程-Measure 参考 <Android开发艺术探索> https://developer.android.google.cn/refe ...

  3. 3D语音天气球(源码分享)——创建可旋转的3D球

    开篇废话: 在9月份时参加了一个网站的比赛,比赛的题目是需要使用第三方平台提供的服务做出创意的作品. 于是我选择使用语音服务,天气服务,Unity3D,Android来制作一个3D语音天气预报,我给它 ...

  4. android 自定义view 前的基础知识

    本篇文章是自己自学自定义view前的准备,具体参考资料来自 Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了 ...

  5. 2017最新的Python教程分享

    Python在数据科学盛行的今天,其易于阅读和编写的特点,越来越受编程者追捧.在IEEE发布的2017年编程语言排行榜中,Python也高居首位.如果你有学Python的计划,快来看看小编分享的Pyt ...

  6. 2017埙箫简谱清单分享(附音频Demo)

    前言 习箫五载,略有所获,皆在坚持. 本博文记录旨在记录练习过程中所录制的Demo以供自省.自娱.自乐,同时记录.分享简谱与箫友(目前为简谱,日后学会线谱后会添加相应谱子分类). 简谱 &&a ...

  7. 回家前的挣扎——SQLite增删改查

    引言 最后一天,公司就两个人,也不知道弄点什么,就在网上找了Sqlite的文档,看了看,这里也是现学现卖,给自己找点事做,感觉时间过得还是比较快的,不然焦急等待,滋味不好受啊. SQLite简介 SQ ...

  8. 2015年末分享:利用RS修改用户密码

    马上就要2016农历新年了,送点什么给大家呢?我觉得还是分享点技术吧.前不久用户在抱怨为什么登录Cognos Connection的密码不能让我们自己改?相信Cognos开发的很多人知道,Cognos ...

  9. 简单跳转到微信分享,基于libWeiChatSDK 和简单的自定义UIActivityViewController

    一.自定义UIActivity: 如果想要自定义UIActivity必须知道UIActivityViewController.首先这个类主要是用于接受字符串,RUL类型和图片类型的数据用于分享和操作的 ...

随机推荐

  1. 浏览器加载外部js 的顺序,以及处理顺序。

    问题, 有事候按F12打开 google的调试台后,查看network下面加载过来的资源是, 有些资源的状态处于 pending.. 个人理解: 浏览器是可以同时开启多个http 请求去加载外部的资源 ...

  2. Ubuntu 12.04下安装thrift 0.9

    Thrift这里就不介绍了,只说一句--Facebook很牛逼. 我这里安装Thrift主要是为Accumulo数据库作准备,所以java语言为必选项. 具体安装参考官方Apache Thrift R ...

  3. POJ3352 Road Construction 双连通分量+缩点

    Road Construction Description It's almost summer time, and that means that it's almost summer constr ...

  4. SQL复习三(子查询)

    子查询 子查询就是嵌套查询,即select中包含这select,如果一条语句中存在着两个,或者两个以上的select,那么就是子查询语句了. 子查询出现的位置 where后,作为条件的一部分: fro ...

  5. linux动态链接库---一篇讲尽

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...

  6. 内层div的margin-top影响外层div——引出外边距合并Collapsing margins

    内层div的margin-top影响外层div——引出外边距合并Collapsing margins 作者:zccst 今天才算是了解边距合并.正如一位前辈所言,每一个CSS的坑,都让你学到不少知识. ...

  7. 扩展对EasyUI的校验规则

    var myReg = RegExp(/[(\*)(\|)(\\)(\:)(\")(\/)(\<)(\>)(\?)]+/); $.extend($.fn.validatebox. ...

  8. WCF应用场景

    WCF全称Windows Communication Foundation,是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NET Framework 3.5的重要组成部分.使用 ...

  9. UVa 10299 - Relatives

    题目大意:Euler's Totient的应用. 几乎和UVa 10179 - Irreducable Basic Fractions一样,于是偷了个懒,直接用10179题的代码,结果WA了,感觉一样 ...

  10. HTML 表单元素之 input 元素

    介绍HTML 5: 表单元素之 input 元素 表单元素之 input 元素 - text, password, url, telephone, email, search, file, radio ...