BubbleView源码解析
2015-11-12 13:43
471 查看
BubbleView源码解析
做IM应用时, 聊天界面的消息一般都有一个背景, 我们叫它为"气泡",
一般这个气泡都使用9patch图片, 但是还有一种方法就是 "自定义View".
下面就来看看github上的一个开源项目吧
BubbleView地址: https://github.com/lguipeng/BubbleView
作者定义了三个BubbleView分别为: BubbleImageView,BubbleTextVew,BubbleLinearLayout
当然最主要的功能类是: BubbleDrawable
关于这些类的用法 ==>
请看这里
效果图如下:
一. 类结构
下面是BubbleView的整体类图:
BubbleImageView, BubbleTextView, BubbleLinearLayoutView都引用了一个BubbleDrawable的实例,
都是通过BubbleDrawable的实例实现"气泡" 功能的, 但是各有不同;
二. BubbleTextView
BubbleTextView重写了onDraw()方法
当然在onDraw方法之前(会收集创建bubbleDrawable对象所需的相关信息并实例化一个对象)会生成bubbleDrawable对象
此方法会先绘制背景, 即气泡背景, 然后调用父类的onDraw()绘制文本
三. BubbleLinearLayoutView
BubbleLinearLayout则重写了onSizeChanged()方法, 在此方法中收集bubbleDrawable对象所需的相关信息, 并实例化, 然后将bubbleDrawable设置为背景
代码如下:
四. BubbleImageView
BubbleImageView同时实现类onDraw()和onSizeChanged()和onLayout()方法.
onDraw方法将绘制工作委托给bubbleDrawable对象, onSizeChanged()和onLayout()方法主要是在view的大小改变时重新构建bubbleDrawable,
当然绘制起泡的任务还是交给了bubbleDrawable对象
代码如下:
注意: 部分省略, setUp方法有几个重载, 但最终都会调用setUp(int, int, int, int, 因此其他省略)
五. BubbleDrawable
此类是实现"气泡"的关键类,
实现原理:
1. 有两种类型的BubbleDrawable, color或者bitmap类型, BubbleDrawable定义了一个bubbleType变量表示,
此类型有具体的BubbleXXXView而定, 一般color类型的BubbleDrawable用于非ImageView, 而bitmap类型的BubbleDrawable用于ImageView
2. color类型的BubbleDrawable是通过Canvas绘制一个纯色的气泡形状而达到目的
3. bitmap类型的BubbleDrawable则需要通过BitmapShader对bitmap进行相关处理, 让后再通过canvas绘制bitmap
源码片段:
4. 重写BubbleDrawable的draw方法, 并调用上述的绘制代码
由于BubbleDrawable类的代码比较多, 就不贴出类, 传送门---->
这里
第一次写源码解析类的博文, 难免出错或者逻辑混乱, 请多多指教
做IM应用时, 聊天界面的消息一般都有一个背景, 我们叫它为"气泡",
一般这个气泡都使用9patch图片, 但是还有一种方法就是 "自定义View".
下面就来看看github上的一个开源项目吧
BubbleView地址: https://github.com/lguipeng/BubbleView
作者定义了三个BubbleView分别为: BubbleImageView,BubbleTextVew,BubbleLinearLayout
当然最主要的功能类是: BubbleDrawable
关于这些类的用法 ==>
请看这里
效果图如下:
一. 类结构
下面是BubbleView的整体类图:
BubbleImageView, BubbleTextView, BubbleLinearLayoutView都引用了一个BubbleDrawable的实例,
都是通过BubbleDrawable的实例实现"气泡" 功能的, 但是各有不同;
二. BubbleTextView
BubbleTextView重写了onDraw()方法
@Override protected void onDraw(Canvas canvas) { if (bubbleDrawable != null) bubbleDrawable.draw(canvas); super.onDraw(canvas); }
当然在onDraw方法之前(会收集创建bubbleDrawable对象所需的相关信息并实例化一个对象)会生成bubbleDrawable对象
此方法会先绘制背景, 即气泡背景, 然后调用父类的onDraw()绘制文本
三. BubbleLinearLayoutView
BubbleLinearLayout则重写了onSizeChanged()方法, 在此方法中收集bubbleDrawable对象所需的相关信息, 并实例化, 然后将bubbleDrawable设置为背景
代码如下:
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (w > 0 && h > 0){ setUp(w, h); //先构建bubbleDrawable, 然后设置为背景 } } private void setUp(int left, int right, int top, int bottom){ if (right < left || bottom < top) return; RectF rectF = new RectF(left, top, right, bottom); bubbleDrawable = new BubbleDrawable.Builder() .rect(rectF) .arrowLocation(mArrowLocation) .bubbleType(BubbleDrawable.BubbleType.COLOR) .angle(mAngle) .arrowHeight(mArrowHeight) .arrowWidth(mArrowWidth) .arrowPosition(mArrowPosition) .bubbleColor(bubbleColor) .build(); } private void setUp(int width, int height){ setUp(getPaddingLeft(), + width - getPaddingRight(), getPaddingTop(), height - getPaddingBottom()); setBackgroundDrawable(bubbleDrawable); }
四. BubbleImageView
BubbleImageView同时实现类onDraw()和onSizeChanged()和onLayout()方法.
onDraw方法将绘制工作委托给bubbleDrawable对象, onSizeChanged()和onLayout()方法主要是在view的大小改变时重新构建bubbleDrawable,
当然绘制起泡的任务还是交给了bubbleDrawable对象
代码如下:
注意: 部分省略, setUp方法有几个重载, 但最终都会调用setUp(int, int, int, int, 因此其他省略)
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (w > 0 && h > 0){ setUp(w, h); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); setUp(); } @Override protected void onDraw(Canvas canvas) { int saveCount = canvas.getSaveCount(); canvas.translate(getPaddingLeft(), getPaddingTop()); if (bubbleDrawable != null) bubbleDrawable.draw(canvas); canvas.restoreToCount(saveCount); } private void setUp(int left, int right, int top, int bottom){ if (right <= left || bottom <= top) return; RectF rectF = new RectF(left, top, right, bottom); if (sourceDrawable != null) mBitmap = getBitmapFromDrawable(sourceDrawable); bubbleDrawable = new BubbleDrawable.Builder() .rect(rectF) .arrowLocation(mArrowLocation) .angle(mAngle) .arrowHeight(mArrowHeight) .arrowWidth(mArrowWidth) .bubbleType(BubbleDrawable.BubbleType.BITMAP) .arrowPosition(mArrowPosition) .bubbleBitmap(mBitmap) .build(); }
五. BubbleDrawable
此类是实现"气泡"的关键类,
实现原理:
1. 有两种类型的BubbleDrawable, color或者bitmap类型, BubbleDrawable定义了一个bubbleType变量表示,
此类型有具体的BubbleXXXView而定, 一般color类型的BubbleDrawable用于非ImageView, 而bitmap类型的BubbleDrawable用于ImageView
2. color类型的BubbleDrawable是通过Canvas绘制一个纯色的气泡形状而达到目的
3. bitmap类型的BubbleDrawable则需要通过BitmapShader对bitmap进行相关处理, 让后再通过canvas绘制bitmap
源码片段:
private void setUp(Canvas canvas){ switch (bubbleType){ case COLOR: mPaint.setColor(bubbleColor); break; case BITMAP: if (bubbleBitmap == null) return; if (mBitmapShader == null){ mBitmapShader = new BitmapShader(bubbleBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } mPaint.setShader(mBitmapShader); setUpShaderMatrix(); break; } setUpPath(mArrowLocation, mPath); canvas.drawPath(mPath, mPaint); }
4. 重写BubbleDrawable的draw方法, 并调用上述的绘制代码
由于BubbleDrawable类的代码比较多, 就不贴出类, 传送门---->
这里
第一次写源码解析类的博文, 难免出错或者逻辑混乱, 请多多指教
相关文章推荐
- 代码:php
- Asteroids(最小点覆盖)
- HttpServletRequest中得到各种信息
- Windows7+Anaconda+Theano+Pylearn2深度学习环境搭建
- 拒绝平庸——浅谈WEB登录页面设计
- CocoaPods安装和使用
- prufer sequence
- HUD 1394 归并求逆序数
- As of ADT 14, resource fields cannot be used as switch cases
- SpringMVC注解@RequestParam全面解析
- Java中的String处理
- iOS 把模拟器中的的.app文件给其他小伙伴,放到他们的模拟器中运行的方法
- Fiddler工具——手机抓包
- PHP - 遍历文件夹下的所有文件名
- iOS学习之关于#import导入补全问题
- 操作系统文件管理
- CF#201 div2 C Alice and Bob(number theory)
- 计算机进程
- php多路复用(多线程)socket相关应用
- Testing Round #12