牛骨文教育服务平台(让学习变的简单)

(一).前言:

今天我们主要来学习一下新的开源框架,TextDrawable。我们经常在一些应用通讯录中看到这样的效果,例如我们加了一个好友,但是该用户没有上传头像图片,那么应用要么默认显示一个默认头像,或者我们就可以自动根据姓名第一个字或者首字母自动生成一个图片。OK,TextDrawable框架(Github地址)就是可以解决这个问题。TextDrawable扩展自Drawable,用于生成文本或者字母的图片的轻量级库,可用于现有/自定义/网络等ImageView类,并且包含一个流接口用于创建drawables以及一个定制的ColorGenerator。效果如下:

FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android

(二).使用方法:

2.1.AS进行集成配置TextDrawable,使用Gradle进行导入: 

       dependencies {
        compile"com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
}

2.2.创建简单的标题:

<ImageViewandroid:layout_width="60dp"
          android:layout_height="60dp"
          android:id="@+id/image_view"/>

[注].为ImageView制定了width和height,那么drawable会自动适应大小。

2.3.创建圆角

TextDrawabledrawable1 = TextDrawable.builder()
                .buildRoundRect("A",Color.RED, 10); // radius in px
TextDrawabledrawable2 = TextDrawable.builder()
                .buildRound("A",Color.RED);

2.4.增加圆角

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字符来创建有趣的标题。

(三).使用实例:

下面我们来具体实例:首先看一下实现的效果:

我们这边创建一个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 同时欢迎大家star和fork整个开源快速开发框架项目~