阿里云服务器免费领卷啦。

捡代码论坛-最全的游戏源码下载技术网站!

 找回密码
 立 即 注 册

QQ登录

只需一步,快速开始

搜索
关于源码区的附件失效或欺骗帖, 处理办法
查看: 11902|回复: 6

[安卓,android源码] 安卓实现下雨,飘雪,红包雨,碰撞球,自定义View 源码

[复制链接]

4208

主题

210

回帖

12万

积分

管理员

管理员

Rank: 9Rank: 9Rank: 9

积分
126075
QQ
发表于 2017-2-21 14:46:18 | 显示全部楼层 |阅读模式
安卓实现下雨,飘雪,红包雨,碰撞球,自定义View 源码。
目录:
  效果展示
  感想
  代码拆解
  开源地址
效果展示
  有没有兴趣继续看下去,直接看下"颜值"是第一步了。依次对应:下雨,飘雪,红包雨,碰撞球.







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

16年总算过去了,跟各位猿友有说句祝福吧,新的一年少加点班,身体健康,钱能赚多少就尽量赚。
  之前看博客园,很多发纯感想的,都被推荐了好几天,说实话,我几乎一拉到底,就看有没有点↓的。
  公司放假时间是在23号,也就明天了,大四实习到现在,一直很忙,这段时间也是我在编程层面上学到了比较多东西的阶段,上面的自定义View是Android的,完成它们是在实习上班期间挤出时间做的,最初的初衷是想把第四个碰撞球的效果加入到毕设里面,现在总算是实现了,过程遇到很多问题,球体的碰撞处理比想象中麻烦很多,前三个比较简单,也是微信,QQ的下表情原理吧,我猜应该是。。。
  毕设最终也会开源,还请大家留意我 GitHbub,这将会是一个集合非第三方IM和仿朋友圈+golang制作服务端等等知识的社交APP。

代码拆解
  如果你仔细看了上面的四张效果图,你会发现,前三张是没碰撞效果处理的,而第四张是具备的。这也是我要区分实现的效果,目的是为了表明,不仅可以不碰撞还可以选择碰。
  同时,飘雪和红包雨,事实也仅仅是图片的不同,这就对了。你只需要修改图片就能实现完全自定义,爱下什么下什么。
  言归正传,整体使用了 适配器设计模式。代码是很简练易懂的,可以看看我的目录结构。


  
  基类是一个暴露绘制和逻辑抽象方法的View子类,所有自定义View需要继承它。子类只需要关注自己要绘制什么,以及我要绘制的东西怎么去不断地改变,逻辑改变设计在一个 Thread 线程里面,采用 postInvalidate 通知 UI 刷新。
  1. <font size="5">/**
  2. * Created by LinGuanHong on 2017/1/15.
  3. *
  4. * My GitHub : https://github.com/af913337456/
  5. *
  6. * My Blog   : http://www.cnblogs.com/linguanh/
  7. *
  8. */

  9. public abstract class BaseView extends View {

  10.     protected String TAG = "zzzzz";
  11.     private static final int sleepTime = 30;
  12.     private RefreshThread refreshThread = null;

  13.     public BaseView(Context context) {
  14.         super(context);
  15.     }

  16.     public BaseView(Context context, AttributeSet attrs) {
  17.         super(context, attrs);
  18.     }

  19.     public abstract void drawSub(Canvas canvas);

  20.     public abstract void baseInit(int width,int height);

  21.     public abstract void logic();

  22.     @Override
  23.     protected final void onDraw(Canvas canvas) {
  24.         if(refreshThread == null){
  25.             refreshThread = new RefreshThread();
  26.             refreshThread.start();
  27.         }else{
  28.             drawSub(canvas);
  29.         }
  30.     }

  31.     @Override
  32.     protected void onDetachedFromWindow() {
  33.         running = false;
  34.         super.onDetachedFromWindow();
  35.     }

  36.     private boolean running = true;
  37.     private class RefreshThread extends Thread{

  38.         @Override
  39.         public void run() {
  40.             baseInit(getWidth(),getHeight());
  41.             while (running){
  42.                 try{
  43.                     logic();
  44.                     postInvalidate();
  45.                     Thread.sleep(sleepTime);
  46.                 }catch (Exception e){
  47.                     Log.d(TAG,e.toString());
  48.                 }
  49.             }
  50.         }
  51.     }
  52. }</font>
复制代码
BaseView 已经是一个可以直接继承的父类了,如果仅仅只是绘制一些比较简单逻辑的自定义View,继承它足以,但是要实现上述的效果,还需要添加多一个抽象类,无论是雨景还是雪景,它们都是个体的集合,也就是说,我们需要一个"景"的抽象。
  ShowView 是一个具备泛型的抽象类,它是景色的制作者,至于是什么景,由你来决定,也就是泛型的传入。例如,我要制造雨景,那么我就传入雨点,雪景就是雪块
  1. <font size="5">/**
  2. * Created by LinGuanHong on 2017/1/15.
  3. *
  4. * My GitHub : https://github.com/af913337456/
  5. *
  6. * My Blog   : http://www.cnblogs.com/linguanh/
  7. *
  8. */

  9. public abstract class ShowView<T extends BaseItem> extends BaseView {

  10.     protected List<T> itemList = new ArrayList<>();
  11.     protected int size = 1;

  12.     public ShowView(Context context) {
  13.         super(context);
  14.     }

  15.     /** 子类实现布局必须要重写这个构造方法 */
  16.     public ShowView(Context context, AttributeSet attrs) {
  17.         super(context, attrs);
  18.     }

  19.     @Override
  20.     public void drawSub(Canvas canvas) {
  21.         for(T t:itemList){
  22.             t.draw(canvas);
  23.         }
  24.     }

  25.     @Override
  26.     public void logic() {
  27.         beforeLogicLoop();
  28.         for(T t:itemList){
  29.             t.move();
  30.         }
  31.     }

  32.     public abstract void beforeLogicLoop();
  33.     public abstract T getItem(int width, int height,Resources resources);
  34.     public abstract int getCount();

  35.     @Override
  36.     public void baseInit(int width, int height) {
  37.         size = getCount();
  38.         Resources resources = getResources();
  39.         for(int i = 0; i< size; i++){
  40.             itemList.add(getItem(width,height,resources));
  41.         }
  42.     }

  43. }</font>
复制代码

由于我们的景色里面的个体可能是各种各样,那么为了使他们都能具备一些公共的属性,需要再抽象一个基础的个体类,共不同的景色个体继承。
  1. <font size="5">/**
  2. * Created by LinGuanHong on 2017/1/15.
  3. *
  4. * My GitHub : https://github.com/af913337456/
  5. *
  6. * My Blog   : http://www.cnblogs.com/linguanh/
  7. *
  8. * 公共的属性和行为
  9. *
  10. */

  11. public abstract class BaseItem {

  12.     protected int width,height;      /** 景内宽高 */
  13.     protected Resources resources;

  14.     public BaseItem(int width,int height,Resources resources){
  15.         this.width  = width;
  16.         this.height = height;
  17.         this.resources = resources;
  18.     }

  19.     public abstract void draw(Canvas canvas); /** 显示 */
  20.     public abstract void move();     /** 运动 */

  21. }</font>
复制代码

OK,到这里基础的类都搞定了,为什么说是适配器模式呢,其实 BaseItem 就是 ViewHolder,ShowView 是 BaseAdapter,下面放下雨的Item 类和雨景。
  注意注释,代码很简练易懂!
  1. <font size="5">/**
  2. * Created by LinGuanHong on 2017/1/15.
  3. *
  4. * 造雨,造多少个,160个,具体是什么雨,交给 item 实现
  5. *
  6. */

  7. public class RainView extends ShowView<RainItem> {


  8.     public RainView(Context context) {
  9.         super(context);
  10.     }

  11.     public RainView(Context context, AttributeSet attrs) {
  12.         super(context, attrs);
  13.     }

  14.     @Override
  15.     public void beforeLogicLoop() {

  16.     }

  17.     @Override
  18.     public RainItem getItem(int width, int height, Resources resources) {
  19.         return new RainItem(width,height,resources); /** 要造的雨,是什么雨就在这里传入 */
  20.     }

  21.     @Override
  22.     public int getCount() { /** 要制作的雨数目 */
  23.         return 160;
  24.     }
  25. }</font>
复制代码
我要制作的雨,随机数可以自定义。

  1. <font size="5">/**
  2. * Created by LinGuanHong on 2017/1/15.
  3. */

  4. public class RainItem extends BaseItem {

  5.     private float opt;
  6.     private int sizeX,sizeY; /** 充当角度 */
  7.     private int startX,startY,stopX,stopY;
  8.     private Paint paint;
  9.     private Random random;

  10.     public RainItem(int width, int height, Resources resources) {
  11.         super(width,height,resources);
  12.         init();
  13.         loopInit();
  14.     }

  15.     @Override
  16.     public void move() {
  17.         startX += sizeX * opt;
  18.         stopX  += sizeX * opt;

  19.         startY += sizeY * opt;
  20.         stopY  += sizeY * opt;
  21.         if(startY > height){
  22.             loopInit();
  23.         }
  24.     }

  25.     @Override
  26.     public void draw(Canvas canvas) {
  27.         Log.d("zzzzz","drawView "+startX+" "+startY+" "+stopX+" "+stopY);
  28.         canvas.drawLine(startX,startY,stopX,stopY,paint);
  29.     }

  30.     private void loopInit(){
  31.         sizeX = 1  + random.nextInt(10);
  32.         sizeY = 10 + random.nextInt(20);

  33.         startX = random.nextInt(width );
  34.         startY = random.nextInt(height);

  35.         opt = 0.2f + random.nextFloat();

  36.         stopX = startX + sizeX;
  37.         stopY = startY + sizeY;
  38.     }

  39.     private void init(){
  40.         paint = new Paint(Paint.ANTI_ALIAS_FLAG); /** 抗锯齿  */
  41.         paint.setColor(0xffffffff); /** a,r,g,b 255,255,255,255 */

  42.         random = new Random();
  43.     }

  44. }</font>
复制代码
到这里总结一下,如果你想实现自己的自定义View,不妨直接继承 BaseView,然后写你自己的 Item,就可以了。
开源地址:
游客,如果您要查看本帖隐藏内容请回复

安卓实现下雨,飘雪,红包雨,碰撞球,自定义View 源码


安卓实现下雨,飘雪,红包雨,碰撞球,自定义View 源码
http://bbs.jiandaima.com/thread-997-1-1.html


原始地址:
  1. http://www.cnblogs.com/linguanh/p/6342099.html
复制代码



捡代码论坛-最全的游戏源码下载技术网站! - 论坛版权郑重声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与捡代码论坛-最全的游戏源码下载技术网站!享有帖子相关版权
3、捡代码论坛版权,详细了解请点击。
4、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。
5、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。 我们不承担任何技术及版权问题,且不对任何资源负法律责任。
6、如无法链接失效或侵犯版权,请给我们来信:jiandaima@foxmail.com

回复

使用道具 举报

0

主题

69

回帖

635

积分

高级会员

Rank: 4

积分
635
发表于 2017-2-22 13:26:11 | 显示全部楼层
登录可见评论
回复

使用道具 举报

0

主题

10

回帖

88

积分

注册会员

Rank: 2

积分
88
发表于 2017-4-27 14:07:23 | 显示全部楼层
登录可见评论
回复

使用道具 举报

0

主题

4

回帖

38

积分

新手上路

Rank: 1

积分
38
发表于 2019-1-4 12:30:44 | 显示全部楼层
登录可见评论
回复

使用道具 举报

0

主题

1

回帖

14

积分

新手上路

Rank: 1

积分
14
发表于 2019-3-26 09:49:16 | 显示全部楼层
登录可见评论
回复

使用道具 举报

0

主题

1

回帖

8

积分

新手上路

Rank: 1

积分
8
发表于 2019-12-23 15:13:18 | 显示全部楼层
登录可见评论
回复

使用道具 举报

0

主题

1

回帖

8

积分

新手上路

Rank: 1

积分
8
发表于 2021-4-27 14:31:12 | 显示全部楼层
登录可见评论
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立 即 注 册

本版积分规则

技术支持
在线咨询
QQ咨询
3351529868

QQ|手机版|小黑屋|捡代码论坛-专业源码分享下载 ( 陕ICP备15015195号-1|网站地图

GMT+8, 2024-3-29 01:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表