Getting square images like gmail app

android, image

Solution

Update 2:

I have fixed some of the bugs and released the code as an open source library at: https://github.com/amulyakhare/TextDrawable. It also include some other features that you might want to check out.

Old Answer:

I recommend you to use the following class `CharacterDrawable` (just copy-paste this):

public class CharacterDrawable extends ColorDrawable {

    private final char character;
    private final Paint textPaint;
    private final Paint borderPaint;
    private static final int STROKE_WIDTH = 10;
    private static final float SHADE_FACTOR = 0.9f;

    public CharacterDrawable(char character, int color) {
        super(color);
        this.character = character;
        this.textPaint = new Paint();
        this.borderPaint = new Paint();

        // text paint settings
        textPaint.setColor(Color.WHITE);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(true);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTextAlign(Paint.Align.CENTER);

        // border paint settings
        borderPaint.setColor(getDarkerShade(color));
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(STROKE_WIDTH);
    }

    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);

        // draw border
        canvas.drawRect(getBounds(), borderPaint);

        // draw text
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        textPaint.setTextSize(height / 2);
        canvas.drawText(String.valueOf(character), width/2, height/2 - ((textPaint.descent() + textPaint.ascent()) / 2) , textPaint);
    }

    @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;
    }
}

Then using this is simple: `new CharacterDrawable('A', 0xFF805781);` by passing the character and the color value (example `Color.RED` or some other color in hex `0xFF805781`):

ImageView imageView = (ImageView) findViewById(R.id.imageView);
CharacterDrawable drawable = new CharacterDrawable('A', 0xFF805781);
imageView.setImageDrawable(drawable); 

or based on your question:

CharacterDrawable drawable = new CharacterDrawable('A', 0xFF805781);    
button.setBackgroundDrawable(drawable);

The `drawable` will scale to fit the size of the `ImageView`. Result will be:

Update: Updated code for adding a border which is of darker shade (automatically picks a dark shade based on the fill color).

1) Change the value of `STROKE_WIDTH` based on your needs for the border thikness.

2) Change the value of `SHADE_FACTOR` for border darkness. If `SHADE_FACTOR` is small (eg. `0.2f`), the border will be darker and vice versa.

Note: You can easily vary the size and font of the character

Problem

I want to show images with alphabets like `gmail app` as shown in the below figure. Are all those images are images to be kept in drawable folder or they are drawn as `square shapes` and then letters are drawn to them? Below is what I tried so far to do dynamically. I got just a square shape. Can someone suggest the way to achieve like in gmail app? ``` GradientDrawable gd = new GradientDrawable(); gd.mutate(); gd.setColor(getResources().getColor(gColors[i])); button.setBackgroundDrawable(gd); ```

Original source

Related problems