## (一).前言:
今天我们主要来学习一下新的开源框架,TextDrawable。我们经常在一些应用通讯录中看到这样的效果,例如我们加了一个好友,但是该用户没有上传头像图片,那么应用要么默认显示一个默认头像,或者我们就可以自动根据姓名第一个字或者首字母自动生成一个图片。OK,TextDrawable框架[(Github地址)](https://github.com/amulyakhare/TextDrawable)就是可以解决这个问题。TextDrawable扩展自Drawable,用于生成文本或者字母的图片的轻量级库,可用于现有/自定义/网络等ImageView类,并且包含一个流接口用于创建drawables以及一个定制的ColorGenerator。效果如下:
![](https://box.kancloud.cn/2016-01-18_569c8eb5222d2.jpg)
FastDev4Android框架项目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)
## (二).使用方法:
2.1.AS进行集成配置TextDrawable,使用Gradle进行导入:
~~~
dependencies {
compile'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
}
~~~
2.2.创建简单的标题:
![](https://box.kancloud.cn/2016-01-18_569c8eb53aa65.jpg)
~~~
<ImageViewandroid:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/image_view"/>
~~~
[注].为ImageView制定了width和height,那么drawable会自动适应大小。
2.3.创建圆角
![](https://box.kancloud.cn/2016-01-18_569c8eb53aa65.jpg)
~~~
TextDrawabledrawable1 = TextDrawable.builder()
.buildRoundRect("A",Color.RED, 10); // radius in px
TextDrawabledrawable2 = TextDrawable.builder()
.buildRound("A",Color.RED);
~~~
2.4.增加圆角
![](https://box.kancloud.cn/2016-01-18_569c8eb5527e9.jpg)
~~~
TextDrawabledrawable = TextDrawable.builder()
.beginConfig()
.withBorder(4) /* thicknessin px */
.endConfig()
.buildRoundRect("A",Color.RED, 10);
~~~
2.5.修改字体格式
~~~
TextDrawabledrawable = TextDrawable.builder()
.beginConfig()
.textColor(Color.BLACK)
.useFont(Typeface.DEFAULT)
.fontSize(30) /* size in px*/
.bold()
.toUpperCase()
.endConfig()
.buildRect("a",Color.RED)
~~~
2.6.使用颜色引擎(颜色生成器)
~~~
ColorGeneratorgenerator = ColorGenerator.MATERIAL; // or use DEFAULT
// generate randomcolor
int color1 =generator.getRandomColor();
// generate colorbased on a key (same key returns the same color), useful for list/grid views
int color2 =generator.getColor("user@gmail.com")
// declare thebuilder object once.
TextDrawable.IBuilderbuilder = TextDrawable.builder()
.beginConfig()
.withBorder(4)
.endConfig()
.rect();
// reuse the builderspecs to create multiple drawables
TextDrawable ic1 =builder.build("A", color1);
TextDrawable ic2 =builder.build("B", color2);
~~~
2.7.制定宽度和高度
~~~
<ImageViewandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image_view"/>
~~~
[注].这边的ImageView采用自使用width/height,可以使用编码来设置drawable的width/heigth。
~~~
TextDrawabledrawable = TextDrawable.builder()
.beginConfig()
.width(60) // width in px
.height(60) // height in px
.endConfig()
.buildRect("A",Color.RED);
ImageView image =(ImageView) findViewById(R.id.image_view);
image.setImageDrawable(drawable);
~~~
2.8.其他特点
* 可以和其他drawables配合使用,和LayerDrawable,InsetDrawable,AnimationDrawable,TranstionDrawable等等结合使用。
* 和其他视图兼容(不仅仅是ImageView),可以把它作为TextView,Button等等控件的背景图片。
* 使用字母或者其他unicode字符来创建有趣的标题。
## (三).使用实例:
下面我们来具体实例:首先看一下实现的效果:
![](https://box.kancloud.cn/2016-01-18_569c8eb575d42.jpg)
我们这边创建一个TextDrawablesTestActivity,在里面使用一个列表来分别展示11中不同的效果分别为:
1. SAMPLE_RECT
2. SAMPLE_ROUND_RECT
3. SAMPLE_ROUND
4. SAMPLE_RECT_BORDER
5. SAMPLE_ROUND_RECT_BORDER
6. SAMPLE_ROUND_BORDER
7. SAMPLE_MULTIPLE_LETTERS
8. SAMPLE_FONT
9. SAMPLE_SIZE
10. SAMPLE_ANIMATION
11. SAMPLE_MISC
具体实现代码如下:
~~~
packagecom.chinaztt.fda.test;
importandroid.graphics.Color;
importandroid.graphics.Typeface;
importandroid.graphics.drawable.AnimationDrawable;
importandroid.graphics.drawable.Drawable;
importandroid.os.Bundle;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.BaseAdapter;
importandroid.widget.ImageView;
importandroid.widget.ListView;
importandroid.widget.TextView;
importcom.amulyakhare.textdrawable.TextDrawable;
importcom.amulyakhare.textdrawable.util.ColorGenerator;
importcom.chinaztt.fda.ui.R;
importcom.chinaztt.fda.ui.base.BaseActivity;
importorg.androidannotations.annotations.AfterViews;
importorg.androidannotations.annotations.EActivity;
importorg.androidannotations.annotations.ItemClick;
importorg.androidannotations.annotations.ViewById;
importorg.w3c.dom.Text;
/**
* 当前类注释:TextDrawables 效果实例演示
* 项目名:FastDev4Android
* 包名:com.chinaztt.fda.test
* 作者:江清清 on 15/11/5 22:13
* 邮箱:jiangqqlmj@163.com
* QQ: 781931404
* 公司:江苏中天科技软件技术有限公司
*/
@EActivity(R.layout.text_drawables_layout)
public classTextDrawablesTestActivity extends BaseActivity {
@ViewById
ListView lv_textdrawable;
private String[] mTitles;
private LayoutInflater mLayoutInflater;
private ColorGenerator mGenerator;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
mTitles=newString[]{"SAMPLE_RECT"
,"SAMPLE_ROUND_RECT","SAMPLE_ROUND"
,"SAMPLE_RECT_BORDER","SAMPLE_ROUND_RECT_BORDER"
,"SAMPLE_ROUND_BORDER"
,"SAMPLE_MULTIPLE_LETTERS",
"SAMPLE_FONT","SAMPLE_SIZE","SAMPLE_ANIMATION","SAMPLE_MISC"
};
mGenerator=ColorGenerator.DEFAULT;
mLayoutInflater=getLayouInflater();
}
@AfterViews
public void showLvDrawable(){
lv_textdrawable.setAdapter(newTextAdapter());
}
class TextAdapter extends BaseAdapter{
@Override
public int getCount() {
return mTitles.length;
}
@Override
public Object getItem(int position) {
return mTitles[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, ViewconvertView, ViewGroup parent) {
Hondler _Hondler=null;
if(convertView==null){
_Hondler=new Hondler();
convertView=mLayoutInflater.inflate(R.layout.text_drawables_item_layout,null);
_Hondler.lv_item_img=(ImageView)convertView.findViewById(R.id.lv_item_img);
_Hondler.lv_item_text=(TextView)convertView.findViewById(R.id.lv_item_text);
convertView.setTag(_Hondler);
}else
{
_Hondler=(Hondler)convertView.getTag();
}
_Hondler.lv_item_text.setText(mTitles[position]);
Drawable drawable=null;
switch (position){
case 0: //SAMPLE_RECT
drawable=TextDrawable.builder().buildRect("R",Color.BLUE);
break;
case 1: //SAMPLE_ROUND_RECT
drawable=TextDrawable.builder().buildRoundRect("S",Color.CYAN,10);
break;
case 2: //SAMPLE_ROUND
drawable=TextDrawable.builder().buildRound("圆",Color.LTGRAY);
break;
case 3: //SAMPLE_RECT_BORDER
drawable=TextDrawable.builder().beginConfig()
.withBorder(5)
.endConfig()
.buildRect("粗",Color.RED);
break;
case 4: //SAMPLE_ROUND_RECT_BORDER
drawable=TextDrawable.builder()
.beginConfig()
.withBorder(5)
.endConfig()
.buildRoundRect("S",Color.argb(220,122,122,1),10);
break;
case 5: //SAMPLE_ROUND_BORDER
drawable=TextDrawable.builder()
.beginConfig().withBorder(5).endConfig()
.buildRound("圆",Color.LTGRAY);
break;
case 6: //SAMPLE_MULTIPLE_LETTERS
drawable=TextDrawable.builder()
.beginConfig()
.fontSize(40)
.toUpperCase()
.endConfig()
.buildRect("AK", mGenerator.getColor("AK"));
break;
case 7: //SAMPLE_FONT
drawable =TextDrawable.builder()
.beginConfig()
.textColor(Color.BLACK)
.useFont(Typeface.SERIF)
.bold()
.toUpperCase()
.endConfig()
.buildRect("a", Color.RED);
break;
case 8: //SAMPLE_SIZE
drawable =TextDrawable.builder()
.beginConfig()
.textColor(Color.BLACK)
.fontSize(30) /*size in px */
.bold()
.toUpperCase()
.endConfig()
.buildRect("a", Color.RED);
break;
case 9: //SAMPLE_ANIMATION
TextDrawable.IBuilderbuilder = TextDrawable.builder()
.rect();
AnimationDrawableanimationDrawable = new AnimationDrawable();
for (int i = 10; i > 0;i--) {
TextDrawable frame =builder.build(String.valueOf(i), mGenerator.getRandomColor());
animationDrawable.addFrame(frame, 1200);
}
animationDrawable.setOneShot(false);
animationDrawable.start();
drawable=(Drawable)animationDrawable;
break;
case 10: //SAMPLE_MISC
drawable=TextDrawable.builder()
.buildRect("M", mGenerator.getColor("Misc"));
break;
}
if(drawable!=null){
_Hondler.lv_item_img.setImageDrawable(drawable);
}
return convertView;
}
}
final static class Hondler{
ImageView lv_item_img;
TextView lv_item_text;
}
@ItemClick(R.id.lv_textdrawable)
public void lv_ItemClick(int position){
showToastMsgShort("点击了TextDrawable列表...");
}
}
~~~
## (四).源码分析:
阅读整个该开源代码,其实实现这个效果只有两个类,ColorGenerator和TextDrawable。ColorGenerator为颜色生成引擎比较简单。
4.1.ColorGenerator.java
~~~
packagecom.amulyakhare.textdrawable.util;
importjava.util.Arrays;
importjava.util.List;
importjava.util.Random;
/**
* @author amulya
* @datetime 14 Oct 2014, 5:20 PM
*/
public classColorGenerator {
//使用默认颜色
public static ColorGenerator DEFAULT;
//使用物料模式颜色
public static ColorGenerator MATERIAL;
static {
DEFAULT = create(Arrays.asList(
0xfff16364,
0xfff58559,
0xfff9a43e,
0xffe4c62e,
0xff67bf74,
0xff59a2be,
0xff2093cd,
0xffad62a7,
0xff805781
));
MATERIAL = create(Arrays.asList(
0xffe57373,
0xfff06292,
0xffba68c8,
0xff9575cd,
0xff7986cb,
0xff64b5f6,
0xff4fc3f7,
0xff4dd0e1,
0xff4db6ac,
0xff81c784,
0xffaed581,
0xffff8a65,
0xffd4e157,
0xffffd54f,
0xffffb74d,
0xffa1887f,
0xff90a4ae
));
}
private final List<Integer> mColors;
private final Random mRandom;
//使用静态方法 来创建对象
public static ColorGeneratorcreate(List<Integer> colorList) {
return new ColorGenerator(colorList);
}
private ColorGenerator(List<Integer>colorList) {
mColors = colorList;
mRandom = newRandom(System.currentTimeMillis());
}
//生成一个随机颜色
public int getRandomColor() {
returnmColors.get(mRandom.nextInt(mColors.size()));
}
//获取具体的衍生
public int getColor(Object key) {
returnmColors.get(Math.abs(key.hashCode()) % mColors.size());
}
}
~~~
4.2.TextDrawable进行构建生成相应的drawble,该采用构建者模式生成,根据我们的需求,来进行相应的构建组装即可。具体代码就不注释了,阅读起来很清晰的。
~~~
packagecom.amulyakhare.textdrawable;
importandroid.graphics.*;
importandroid.graphics.drawable.ShapeDrawable;
importandroid.graphics.drawable.shapes.OvalShape;
importandroid.graphics.drawable.shapes.RectShape;
importandroid.graphics.drawable.shapes.RoundRectShape;
/**
* @author amulya
* @datetime 14 Oct 2014, 3:53 PM
*/
public classTextDrawable extends ShapeDrawable {
private final Paint textPaint;
private final Paint borderPaint;
private static final float SHADE_FACTOR =0.9f;
private final String text;
private final int color;
private final RectShape shape;
private final int height;
private final int width;
private final int fontSize;
private final float radius;
private final int borderThickness;
private TextDrawable(Builder builder) {
super(builder.shape);
// shape properties
shape = builder.shape;
height = builder.height;
width = builder.width;
radius = builder.radius;
// text and color
text = builder.toUpperCase ?builder.text.toUpperCase() : builder.text;
color = builder.color;
// text paint settings
fontSize = builder.fontSize;
textPaint = new Paint();
textPaint.setColor(builder.textColor);
textPaint.setAntiAlias(true);
textPaint.setFakeBoldText(builder.isBold);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTypeface(builder.font);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setStrokeWidth(builder.borderThickness);
// border paint settings
borderThickness =builder.borderThickness;
borderPaint = new Paint();
borderPaint.setColor(getDarkerShade(color));
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderThickness);
// drawable paint color
Paint paint = getPaint();
paint.setColor(color);
}
private int getDarkerShade(int color) {
return Color.rgb((int)(SHADE_FACTOR *Color.red(color)),
(int)(SHADE_FACTOR *Color.green(color)),
(int)(SHADE_FACTOR *Color.blue(color)));
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Rect r = getBounds();
// draw border
if (borderThickness > 0) {
drawBorder(canvas);
}
int count = canvas.save();
canvas.translate(r.left, r.top);
// draw text
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);
}
private void drawBorder(Canvas canvas) {
RectF rect = new RectF(getBounds());
rect.inset(borderThickness/2,borderThickness/2);
if (shape instanceof OvalShape) {
canvas.drawOval(rect, borderPaint);
}
else if (shape instanceofRoundRectShape) {
canvas.drawRoundRect(rect, radius,radius, borderPaint);
}
else {
canvas.drawRect(rect, borderPaint);
}
}
@Override
public void setAlpha(int alpha) {
textPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf){
textPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
return width;
}
@Override
public int getIntrinsicHeight() {
return height;
}
public static IShapeBuilder builder() {
return new Builder();
}
public static class Builder implementsIConfigBuilder, IShapeBuilder, IBuilder {
private String text;
private int color;
private int borderThickness;
private int width;
private int height;
private Typeface font;
private RectShape shape;
public int textColor;
private int fontSize;
private boolean isBold;
private boolean toUpperCase;
public float radius;
private Builder() {
text = "";
color = Color.GRAY;
textColor = Color.WHITE;
borderThickness = 0;
width = -1;
height = -1;
shape = new RectShape();
font =Typeface.create("sans-serif-light", Typeface.NORMAL);
fontSize = -1;
isBold = false;
toUpperCase = false;
}
public IConfigBuilder width(int width){
this.width = width;
return this;
}
public IConfigBuilder height(intheight) {
this.height = height;
return this;
}
public IConfigBuilder textColor(intcolor) {
this.textColor = color;
return this;
}
public IConfigBuilder withBorder(intthickness) {
this.borderThickness = thickness;
return this;
}
public IConfigBuilder useFont(Typefacefont) {
this.font = font;
return this;
}
public IConfigBuilder fontSize(intsize) {
this.fontSize = size;
return this;
}
public IConfigBuilder bold() {
this.isBold = true;
return this;
}
public IConfigBuilder toUpperCase() {
this.toUpperCase = true;
return this;
}
@Override
public IConfigBuilder beginConfig() {
return this;
}
@Override
public IShapeBuilder endConfig() {
return this;
}
@Override
public IBuilder rect() {
this.shape = new RectShape();
return this;
}
@Override
public IBuilder round() {
this.shape = new OvalShape();
return this;
}
@Override
public IBuilder roundRect(int radius) {
this.radius = radius;
float[] radii = {radius, radius,radius, radius, radius, radius, radius, radius};
this.shape = newRoundRectShape(radii, null, null);
return this;
}
@Override
public TextDrawable buildRect(Stringtext, int color) {
rect();
return build(text, color);
}
@Override
public TextDrawablebuildRoundRect(String text, int color, int radius) {
roundRect(radius);
return build(text, color);
}
@Override
public TextDrawable buildRound(Stringtext, int color) {
round();
return build(text, color);
}
@Override
public TextDrawable build(String text,int color) {
this.color = color;
this.text = text;
return new TextDrawable(this);
}
}
public interface IConfigBuilder {
public IConfigBuilder width(int width);
public IConfigBuilder height(intheight);
public IConfigBuilder textColor(intcolor);
public IConfigBuilder withBorder(intthickness);
public IConfigBuilder useFont(Typefacefont);
public IConfigBuilder fontSize(intsize);
public IConfigBuilder bold();
public IConfigBuilder toUpperCase();
public IShapeBuilder endConfig();
}
public static interface IBuilder {
public TextDrawable build(String text,int color);
}
public static interface IShapeBuilder {
public IConfigBuilder beginConfig();
public IBuilder rect();
public IBuilder round();
public IBuilder roundRect(int radius);
public TextDrawable buildRect(Stringtext, int color);
public TextDrawablebuildRoundRect(String text, int color, int radius);
public TextDrawable buildRound(Stringtext, int color);
}
}
~~~
我们的项目已经配置集成了TextDrawble的例子,大家以后在做通讯录相关的应用的时候列表中的图标根据根据姓名去设置了。同时欢迎大家去Github站点进行clone或者下载浏览:
[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android) 同时欢迎大家star和fork整个开源快速开发框架项目~
- 前言
- Android快速开发框架介绍(一)
- Android首页图片自动无限循环轮播Gallery+FlowIndicator(二)
- Android 列表下拉刷新组件PullToRefreshListView使用(三)
- Android 数据缓存器ACache的详解和使用(四)
- Android崩溃异常捕捉CustomCrash,提升用户体验(五)
- Android实现沉浸式状态栏(六)
- AndroidAnnnotations注入框架介绍和Android Studios基本配置(七)
- AndroidAnnnotations注入框架的工作原理(八)
- AndroidAnnnotations注入框架使用之注入组件Components(九)
- AndroidAnnnotations注入框架使用之Injection标签详解(十)
- AndroidAnnnotations注入框架使用之事件绑定Event Binding(十一)
- AndroidAnnnotations注入框架使用之线程处理Threading(十二)
- AndroidAnnnotations注入框架使用之第三方框架集成RoboGuice(十三)
- AndroidAnnnotations注入框架使用之第三方框架集成Otto事件总线(十四)
- AndroidAnnnotations注入框架使用之第三方框架集成OrmLite(十五)
- AndroidAnnnotations注入框架使用之最佳实践之Adapters和lists(十六)
- AndroidAnnnotations注入框架使用之最佳实践SharedPreferences(十七)
- Android MVP开发模式详解(十九)
- 消息总线EventBus的基本使用(二十)
- 消息总线EventBus源码分析以及与Otto框架对比(二十一)
- 列表头生成带文本或者字母的图片开源库TextDrawable使用和详解(二十二)
- 重写WebView网页加载以及JavaScript注入详解(二十三)
- BaseAdapterHelper的基本使用介绍,让你摆脱狂写一堆Adapter烦恼(二十四)
- BaseAdapterHelper详解源码分析,让你摆脱狂写一堆Adapter烦恼(二十五)
- Volley完全解析之基础使用(二十六)
- Volley完全解析之进阶最佳实践与二次封装(二十七)
- RecyclerView完全解析,让你从此爱上它(二十八)
- RecyclerView完全解析之打造新版类Gallery效果(二十九)
- RecyclerView完全解析之结合AA(Android Annotations)注入框架实例(三十)
- RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)
- CardView完全解析与RecyclerView结合使用(三十二)
- 神器ViewDragHelper完全解析,妈妈再也不担心我自定义ViewGroup滑动View操作啦~(三十三)
- 神器ViewDragHelper完全解析之详解实现QQ5.X侧滑酷炫效果(三十四)
- 实例解析之SwipeRefreshLayout+RecyclerView+CardView(三十五)
- HorizontalScrollView,Fragment,FragmentStatePagerAdapter打造网易新闻Tab及滑动页面效果(三十六)
- Android Design支持库TabLayout打造仿网易新闻Tab标签效果(三十七)
- 打造QQ6.X最新版本侧滑界面效果(三十八)