这次的自定义view的要求效果为:能随机生成气泡 气泡会匀速上浮 保持屏幕始终存在n个气泡;

(一)随机生成气泡

首先要绘制一个气泡需要以下几个参数: float x, y; 气泡坐标 int radius 气泡半径 int color 气泡颜色 int speed 气泡移动速度 为了方便绘制这里建议把这几个参数分装起来成为一个气泡对象。

//定义buble 对象
public class Bubble{
//颜色
public int color;
//位置
public float point_y;
public float point_x;
//移动速度
public float speed;
//半径
public int radius;
public Bubble(){}
}

现在要做到随机生成气泡的color,x轴位置 ,移动速度,半径。y轴位置固定为view的最底部。

这里写一个Bubble_create(int width)方法 传入当前view的宽度。

private   Bubble Bubble_create(int witdh){Bubble bubble = new Bubble();Random rand = new Random();switch (rand.nextInt(10)){case 0:bubble.color = Color.BLUE;break;case 1:bubble.color = Color.BLACK;break;case 2:bubble.color = Color.CYAN;break;case 3:bubble.color = Color.DKGRAY;break;case 4:bubble.color = Color.GRAY;break;case 5:bubble.color = Color.GREEN;break;case 6:bubble.color = Color.YELLOW;break;case 7:bubble.color = Color.LTGRAY;break;case 8:bubble.color = Color.MAGENTA;break;case 9:bubble.color = Color.RED;break;default:bubble.color = Color.BLUE;break;}bubble.radius = rand.nextInt(70)+10;bubble.point_x = rand.nextInt(witdh);bubble.point_y = getHeight();bubble.speed = rand.nextInt(10)+1;return bubble;}
//调用方法
Bubble mbuble = Bubble_create(getWidth());

(二)气泡匀速上升

重点!重点!这里开始自定义surfaceView. 先搭自定义surfaceView的框架

第一步: 继承suerfaceview 实现它的几个构造函数。 第二步: implements SurfaceHolder.Callback与 Runnable的接口

//surfaceview 框架
public class BubbleView extends SurfaceView implements SurfaceHolder.Callback,Runnable {//surfaceHolders 这个很重要用来锁定canvas和解锁canvasprivate SurfaceHolder mSurfaceHolder;//程序运行标志 用来控制是否继续绘制viewprivate  boolean running;// 画布private Canvas mCanvas;public BubbleView(Context context) {super(context);init();}public BubbleView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public BubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}//将初始化操作放到这里protected void init(){mSurfaceHolder =  getHolder();mSurfaceHolder.addCallback(this);setFocusable(true);setFocusableInTouchMode(true);this.setKeepScreenOn(true);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {running = true;new Thread(this).start();}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
//        running = false;}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {running = false;}@Overridepublic void run() {//运行线程 循环绘制while(running){draw();}try {//等60毫秒绘制一次Thread.sleep(60);} catch (InterruptedException e) {e.printStackTrace();}}//这里执行绘制方法public void draw(){try {mCanvas = mSurfaceHolder.lockCanvas();//这里很重要 每次绘制的时候绘制一个白色背景来作为刷新界面的方式//因为surfaceview 不会清除上次绘制的图形mCanvas.drawColor(Color.WHITE);} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null){mSurfaceHolder.unlockCanvasAndPost(mCanvas);}}}
}

第三步:实现气泡上升。

//定义private List<Bubble> bubbles;private Paint bubbles_paint;
//初始化bubbles = new ArrayList<>();bubbles_paint = new Paint();bubbles_paint.setStyle(Paint.Style.FILL);
//下面一部分要放到绘制里面
//这里是遍历气泡list里的所有气泡并且绘制出来for (Bubble temp_bubble:bubbles) {//这里一段是实现气泡的颜色渐变RadialGradient radialGradient =new RadialGradient(temp_bubble.point_x,temp_bubble.point_y,temp_bubble.radius, new int[]{Color.WHITE, 0xFFf1f2f2, temp_bubble.color },null, Shader.TileMode.CLAMP);bubbles_paint.setShader(radialGradient);
//这里绘制气泡圆形mCanvas.drawCircle(temp_bubble.point_x,temp_bubble.point_y,temp_bubble.radius,bubbles_paint);
//绘制完后把气泡的y轴坐标往上挪speed的距离temp_bubble.point_y -= temp_bubble.speed;}

(三)保持屏幕始终存在n个气泡:

1.在每次绘制的时候判断气泡list的数量是否少于n个少于n个的话就创建。 2.当气泡飞出屏幕外的时候要把它从列表中移除掉。

 //1.在每次绘制的时候判断气泡list的数量是否少于n个少于n个的话就创建。while(bubbles.size()<=10){Log.d(this.toString(),bubbles.size()+"");bubbles.add(Bubble_create(getWidth()));}····这里绘制气泡 ····// 2.当气泡飞出屏幕外的时候要把它从列表中移除掉。//这里是创建一个temp气泡列表 把还在屏幕里的气泡塞到这个列表中,最后替换掉之前的气泡列表。List<Bubble> temp_bubbles = new ArrayList<>();for(Bubble temp_bubble:bubbles){if((int)temp_bubble.point_y+temp_bubble.radius>=0){temp_bubbles.add(temp_bubble);}}bubbles = temp_bubbles;
所有需求都实现后把它们整合到自定义view里面 最后的源码:
public class BubbleView extends SurfaceView implements SurfaceHolder.Callback,Runnable {private SurfaceHolder mSurfaceHolder;private  boolean running;// 画布private Canvas mCanvas;//气泡列队private List<Bubble> bubbles;private Paint bubbles_paint;public BubbleView(Context context) {super(context);init();}public BubbleView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public BubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}protected void init(){mSurfaceHolder =  getHolder();mSurfaceHolder.addCallback(this);setFocusable(true);setFocusableInTouchMode(true);this.setKeepScreenOn(true);bubbles = new ArrayList<>();bubbles_paint = new Paint();bubbles_paint.setStyle(Paint.Style.FILL);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {running = true;new Thread(this).start();}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
//        running = false;}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {running = false;}@Overridepublic void run() {while(running){draw();}try {Thread.sleep(60);} catch (InterruptedException e) {e.printStackTrace();}}public void draw(){try {mCanvas = mSurfaceHolder.lockCanvas();mCanvas.drawColor(Color.WHITE);while(bubbles.size()<=10){Log.d(this.toString(),bubbles.size()+"");bubbles.add(Bubble_create(getWidth()));}for (Bubble temp_bubble:bubbles) {RadialGradient radialGradient =new RadialGradient(temp_bubble.point_x,temp_bubble.point_y,temp_bubble.radius, new int[]{Color.WHITE, 0xFFf1f2f2, temp_bubble.color },null, Shader.TileMode.CLAMP);bubbles_paint.setShader(radialGradient);mCanvas.drawCircle(temp_bubble.point_x,temp_bubble.point_y,temp_bubble.radius,bubbles_paint);temp_bubble.point_y -= temp_bubble.speed;}List<Bubble> temp_bubbles = new ArrayList<>();for(Bubble temp_bubble:bubbles){if((int)temp_bubble.point_y+temp_bubble.radius>=0){temp_bubbles.add(temp_bubble);}}bubbles = temp_bubbles;} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null){mSurfaceHolder.unlockCanvasAndPost(mCanvas);}}}//定义buble 对象public class Bubble{//颜色public int color;//位置public float point_y;public float point_x;//移动速度public float speed;//半径public int radius;public Bubble(){}}private   Bubble Bubble_create(int witdh){Bubble bubble = new Bubble();Random rand = new Random();switch (rand.nextInt(10)){case 0:bubble.color = Color.BLUE;break;case 1:bubble.color = Color.BLACK;break;case 2:bubble.color = Color.CYAN;break;case 3:bubble.color = Color.DKGRAY;break;case 4:bubble.color = Color.GRAY;break;case 5:bubble.color = Color.GREEN;break;case 6:bubble.color = Color.YELLOW;break;case 7:bubble.color = Color.LTGRAY;break;case 8:bubble.color = Color.MAGENTA;break;case 9:bubble.color = Color.RED;break;default:bubble.color = Color.BLUE;break;}bubble.radius = rand.nextInt(70)+10;bubble.point_x = rand.nextInt(witdh);bubble.point_y = getHeight();bubble.speed = rand.nextInt(10)+1;return bubble;}
}

在layout布局中放入这个view就可以了。 

[自定义SurfaceView] 气泡效果相关推荐

  1. android 气泡.9,Android 三种方式实现三角形气泡效果、自定义View、shape、点9图

    背景 这期需求中,项目需要这样一个情况,就是二级菜单上面有个三角形 乍一看,用个图片就可以解决,一个线性布局.垂直摆下去,所以一开始我是这样尝试的,后来发现美工给我切的图很不合适,不同手机显示效果也不 ...

  2. android坐标判断三角形,Android实现三角形气泡效果方式汇总

    在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...

  3. Android带三角形的弹窗,Android实现三角形气泡效果方式汇总

    在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...

  4. android气泡样式图片,Android实现三角形气泡效果方式汇总

    在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...

  5. 七天免登录(Cookie+session)+ 页面显示动画人物效果(萌娘+气泡效果)+购物车的实现代码

    一.七天免登录(Cookie+session),基于实现jsp页面 页面效果:勾选7天免登录复选框,输入用户名和密码,点击登录即可,登录后可在cookie中查看用户登录信息,以及用户过期时间 1.登录 ...

  6. Android qq消息气泡实现效果,Android 实现仿QQ拖拽气泡效果的示例

    效果图: 一.实现思路 在列表中默认使用自定义的TextView控件来展示消息气泡,在自定义的TextView控件中重写onTouchEvent方法,然后在DOWN.MOVE.UP事件中分别处理拖拽效 ...

  7. Unity 实现自定义图片破碎效果-2D_Destruction

    Unity 实现自定义图片破碎效果-2D_Destruction 导引 效果预览 源码下载地址 实现流程 1.添加SrpiteRenderer组件 2.添加Explodable组件 3.Polygon ...

  8. Android实现三角形气泡效果方式汇总

    在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...

  9. 分享Css3设计---纯Css实现超酷的iphone玻璃气泡效果

    最近做手机项目时候,需要实现一个类似iphone SMS效果的气泡效果. 这里分享下实现心得, 首先分析下iphone的气泡效果有一下特点 1. 圆角 2. 向下的外阴影 3. 上边和下边的内阴影 4 ...

最新文章

  1. 完全免费,简化版Plotly推出,秒绘各类可视化图表
  2. 【性能优化】纳尼?内存又溢出了?!是时候总结一波了!!
  3. C#-CHTTPDownload
  4. 傅里叶变换的初级理解一
  5. 《吃土》全书笔记整理
  6. win10无法查看计算机名,win10如何查看计算机名字
  7. 为什么学习C语言这么久,看的懂代码,做不出题,写不出来项目?
  8. 在Linux下编写C程序,怎么检查程序是否有内存泄漏?
  9. 浙江经济职业技术学院计算机排名,浙江经济职业技术学院排名第几
  10. var,object和dynamic
  11. 好书推荐_Windows程序设计(第五版)
  12. MCMC算法—MH算法的Python实现(一)
  13. 《Head First 设计模式》(一):策略模式
  14. android view translateanimation,Android:有没有办法在TranslateAnimation之后获得View的最新位置?...
  15. 安装liunx出现Entering emergency mode
  16. Kotlin:关于Sealed密封类
  17. 解绑数字身份,解锁新玩法与构建方式(下)
  18. codeforces round#517
  19. OpenCV之Python学习笔记
  20. A-Level经济例题解析及练习 Identifying a firm‘s profit

热门文章

  1. 「P8t.ch」靠卖QR-Code实体商品,想变成下一个TinyURL
  2. API 帮产品度过瓶颈期
  3. winserver2019 解决【你的远程桌面许可证出现问题,你的会话将在60分钟后断开连接】
  4. liunx安装oracle11g
  5. Builder (建造者)模式
  6. springTask与quartz比较
  7. markdown黑色背景代码生成(良心版)
  8. 短视频矩阵-短视频seo源码开发搭建
  9. AVS3:对称运动矢量差SMVD
  10. 非常完善的Log4net详细说明