天天看點

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)

轉載請标明出處: 

http://blog.csdn.net/developer_jiangqq/article/details/49680415

本文出自:【江清清的部落格】

(一).前言:   

          【好消息】個人網站已經上線運作,後面部落格以及技術幹貨等精彩文章會同步更新,請大家關注收藏:http://www.lcode.org

          今天我們主要來學習一下新的開源架構,TextDrawable。我們經常在一些應用通訊錄中看到這樣的效果,例如我們加了一個好友,但是該使用者沒有上傳頭像圖檔,那麼應用要麼預設顯示一個預設頭像,或者我們就可以自動根據姓名第一個字或者首字母自動生成一個圖檔。OK,TextDrawable架構(Github位址)就是可以解決這個問題。TextDrawable擴充自Drawable,用于生成文本或者字母的圖檔的輕量級庫,可用于現有/自定義/網絡等ImageView類,并且包含一個流接口用于建立drawables以及一個定制的ColorGenerator。效果如下:

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)

       FastDev4Android架構項目位址:https://github.com/jiangqqlmj/FastDev4Android

(二).使用方法:   

       2.1.AS進行內建配置TextDrawable,使用Gradle進行導入: 

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

     2.2.建立簡單的标題:

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)
<ImageViewandroid:layout_width="60dp"
          android:layout_height="60dp"
          android:id="@+id/image_view"/>
           

[注].為ImageView制定了width和height,那麼drawable會自動适應大小。

2.3.建立圓角

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)
TextDrawabledrawable1 = TextDrawable.builder()
                .buildRoundRect("A",Color.RED, 10); // radius in px
TextDrawabledrawable2 = TextDrawable.builder()
                .buildRound("A",Color.RED);
           

2.4.增加圓角

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)
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("[email protected]")
 
// 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字元來建立有趣的标題。

(三).使用執行個體:   

下面我們來具體執行個體:首先看一下實作的效果:

【FastDev4Android架構開發】清單頭生成帶文本或者字母的圖檔開源庫TextDrawable使用和詳解(二十二)

我們這邊建立一個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
 * 郵箱:[email protected]
 * 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整個開源快速開發架構項目~