深度剖析之 TextDrawable
2016-01-07 17:58
141 查看
剖析项目名称: TextDrawable
剖析原项目地址:https://github.com/amulyakhare/TextDrawable
剖析理由:只知其然而不知其所以然,如此不好。想要快速的进阶,不走寻常路,剖析开源项目,深入理解扩展知识,仅仅这样还不够,还需要如此:左手爱哥的设计模式,右手重构改善既有设计,如此漫长打坐,回过头再看来时的路,书已成山,相信翔哥说的,量变引起质变
先看整体效果图:
这个轻量级的库提供了矩形、圆角、圆形的文本图供ImageView使用。Android Studio项目导入:
xml引用实例(指定ImageView宽度/高度和可拉的自动扩展以适应大小。):
代码调用实例和效果:
以上实例才用的是默认图形,我们还可以选择圆角或圆形,可以设置边框,代码调用实例和效果图如下:
修改字体样式代码调用实例:
颜色辅助类调用实例:
大概聊了整个项目后,发现需要我们有两个类:ColorGenerator 和 TextDrawable ,ColorGenerator 内部预定义了一些了的色值存放到集合,然后需要用时再从里面取出,这里就不细说了,重点放在TextDrawable
,该类运用builder模式,设置相关属性,构建TextDrawable,先来看下主体结构:
TextDrawable的构造函数调用的父类的含shape构造方法,而这里的传入Builder类在初始化的时候就初始化了shape的子类RectShape:
改变图形本质通过改变Shape,ondraw绘制达到目的,实例如下:
这里的Builder模式运用让我眼前一亮,原来还可以这样O(∩_∩)O哈哈~,一个类实现三个借口,每个借口的函数返回可以是不同的接口,这样有个好处就是当你.xx()列出来的方法只会列出接口对应的和Builder自定义的方法,而不会完全列出builder含有的方法
接着再来看TextDrawable的onDraw绘制方法:
基本的绘制方法就不提了,这里值得一说也就文字绘制的位置计算,当你了解了Paint的一下几个属性,想必你就能更容易理解了。
小结:看完这个项目,学到了两点知识:builder模式的另一种优雅实现和画笔绘制计算中心点
参考资料:http://www.zybang.com/question/bd3d73c504008384be0ec0d1daa33bec.html
剖析原项目地址:https://github.com/amulyakhare/TextDrawable
剖析理由:只知其然而不知其所以然,如此不好。想要快速的进阶,不走寻常路,剖析开源项目,深入理解扩展知识,仅仅这样还不够,还需要如此:左手爱哥的设计模式,右手重构改善既有设计,如此漫长打坐,回过头再看来时的路,书已成山,相信翔哥说的,量变引起质变
先看整体效果图:
这个轻量级的库提供了矩形、圆角、圆形的文本图供ImageView使用。Android Studio项目导入:
repositories{ maven { url 'http://dl.bintray.com/amulyakhare/maven' } } dependencies { compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' }
xml引用实例(指定ImageView宽度/高度和可拉的自动扩展以适应大小。):
<ImageView android:layout_width="60dp" android:layout_height="60dp" android:id="@+id/image_view"/>
代码调用实例和效果:
TextDrawable drawable = TextDrawable.builder() .buildRect("A", Color.RED); ImageView image = (ImageView) findViewById(R.id.image_view); image.setImageDrawable(drawable);
以上实例才用的是默认图形,我们还可以选择圆角或圆形,可以设置边框,代码调用实例和效果图如下:
TextDrawable drawable1 = TextDrawable.builder() .buildRoundRect("A", Color.RED, 10); // radius in px TextDrawable drawable2 = TextDrawable.builder() .buildRound("A", Color.RED); TextDrawable drawable = TextDrawable.builder() .beginConfig() .withBorder(4) /* thickness in px */ .endConfig() .buildRoundRect("A", Color.RED, 10);
修改字体样式代码调用实例:
TextDrawable drawable = TextDrawable.builder() .beginConfig() .textColor(Color.BLACK) .useFont(Typeface.DEFAULT) .fontSize(30) /* size in px */ .bold() .toUpperCase() .endConfig() .buildRect("a", Color.RED)
颜色辅助类调用实例:
ColorGenerator generator = ColorGenerator.MATERIAL; // or use DEFAULT // generate random color int color1 = generator.getRandomColor(); // generate color based on a key (same key returns the same color), useful for list/grid views int color2 = generator.getColor("user@gmail.com") // declare the builder object once. TextDrawable.IBuilder builder = TextDrawable.builder() .beginConfig() .withBorder(4) .endConfig() .rect(); // reuse the builder specs to create multiple drawables TextDrawable ic1 = builder.build("A", color1); TextDrawable ic2 = builder.build("B", color2);
大概聊了整个项目后,发现需要我们有两个类:ColorGenerator 和 TextDrawable ,ColorGenerator 内部预定义了一些了的色值存放到集合,然后需要用时再从里面取出,这里就不细说了,重点放在TextDrawable
,该类运用builder模式,设置相关属性,构建TextDrawable,先来看下主体结构:
/** * @author amulya * @datetime 14 Oct 2014, 3:53 PM */ public class TextDrawable extends ShapeDrawable { private TextDrawable(Builder builder) { //调用父类构造含shape super(builder.shape); // 把Builder属性引用到ShapeDrawable shape = builder.shape; height = builder.height; width = builder.width; radius = builder.radius; //...............此处略...................... // 初始化画笔 Paint paint = getPaint(); paint.setColor(color); } public static interface IBuilder {...} public static interface IShapeBuilder {...} public interface IConfigBuilder {...} public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder {...} }
TextDrawable的构造函数调用的父类的含shape构造方法,而这里的传入Builder类在初始化的时候就初始化了shape的子类RectShape:
private Builder() { //初始化基本属性 text = ""; color = Color.GRAY; shape = new RectShape(); //..........此处略............ }
改变图形本质通过改变Shape,ondraw绘制达到目的,实例如下:
@Override public IBuilder roundRect(int radius) { this.radius = radius; float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius}; this.shape = new RoundRectShape(radii, null, null); return this; }
这里的Builder模式运用让我眼前一亮,原来还可以这样O(∩_∩)O哈哈~,一个类实现三个借口,每个借口的函数返回可以是不同的接口,这样有个好处就是当你.xx()列出来的方法只会列出接口对应的和Builder自定义的方法,而不会完全列出builder含有的方法
public static interface IShapeBuilder { //...........此处略........... public IConfigBuilder beginConfig(); } public interface IConfigBuilder { //...........此处略........... public IShapeBuilder endConfig(); } public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder { //...............此处略........................ @Override public IConfigBuilder beginConfig() { return this; } @Override public IShapeBuilder endConfig() { return this; } }
接着再来看TextDrawable的onDraw绘制方法:
@Override public void draw(Canvas canvas) { super.draw(canvas); Rect r = getBounds(); // 如果边框大小大于0则绘制边框 if (borderThickness > 0) { drawBorder(canvas); } int count = canvas.save(); canvas.translate(r.left, r.top); // 绘制文字 int width = this.width < 0 ? r.width() : this.width; int height = this.height < 0 ? r.height() : this.height; int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize; textPaint.setTextSize(fontSize); canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint); canvas.restoreToCount(count); }
基本的绘制方法就不提了,这里值得一说也就文字绘制的位置计算,当你了解了Paint的一下几个属性,想必你就能更容易理解了。
1.基准点是baseline(单行) 2.Paint.ascent:是baseline之上至字符最高处的距离 3.Paint.descent:是baseline之下至字符最低处的距离 4.Paint.leading:是上一行字符的descent到下一行的ascent之间的距离,也就是相邻行间的空白距离 5.Paint.top:是指的是最高字符到baseline的值,即ascent的最大值 6.Paint.bottom:是指最低字符到baseline的值,即descent的最大值
小结:看完这个项目,学到了两点知识:builder模式的另一种优雅实现和画笔绘制计算中心点
参考资料:http://www.zybang.com/question/bd3d73c504008384be0ec0d1daa33bec.html
相关文章推荐
- c#中Dictionary<object, object>存储网络字符取值问题
- ExtJs combobox 下拉图标
- Android内存管理之java虚拟机的GC
- 遍历器构造。
- elasticsearch field data 内存控制
- 腾讯干货!超实用的高清图标SVG解决方案全总结2
- @autoreleasepool-内存的分配与释放
- 安卓adb-截图/录屏命令,保存到SD卡,导出到本地
- EncodingUtils 编译不通过
- 如何修改状态栏的色值
- Windows下的SysWow64和System32
- unity3d UGUI教程之-UGUI 实现刮刮卡橡皮擦
- 设置php编译功能
- 当程序媛闲下来了的时候
- 考上好大学,然后进入IT行业是穷人孩子晋级中产的唯一出路?
- 伯努利方程
- 2016年1月编程语言排行榜:Java荣获2015年度冠军
- 查看 Apache并发请求数及其TCP连接状态
- 原生ajax写法
- CSS基础之颜色值和长度值设置