109

I have a view, I'm drawing with the Canvas object in the onDraw(Canvas canvas) method. My code is:

Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Style.FILL);
canvas.drawPaint(paint);

paint.setColor(android.R.color.black);
paint.setTextSize(20);
canvas.drawText("Some Text", 10, 25, paint);

The problem is the text doesn't show through the background, what am I doing wrong? If I remove the canvas.drawPaint(paint) and paint.setColor(android.R.color.black) you can see the text on the screen.....

Loktar
  • 34,764
  • 7
  • 90
  • 104
Gaz
  • 3,855
  • 6
  • 28
  • 33

2 Answers2

182

Worked this out, turns out that android.R.color.black is not the same as Color.BLACK. Changed the code to:

Paint paint = new Paint(); 
paint.setColor(Color.WHITE); 
paint.setStyle(Style.FILL); 
canvas.drawPaint(paint); 

paint.setColor(Color.BLACK); 
paint.setTextSize(20); 
canvas.drawText("Some Text", 10, 25, paint); 

and it all works fine now!!

Gaz
  • 3,855
  • 6
  • 28
  • 33
  • 41
    Yes. If you want to use the colour definition in the `res/colors.xml` file with the ID `R.color.black`, then you can't just use the ID. If you want to get the actual colour value from the resources, use `paint.setColor(getResources().getColor(R.color.black));` – Matt Gibson Dec 07 '11 at 20:49
  • Anybody know how to draw text in Android Canvas ShapeDrawable with [RectShape](http://stackoverflow.com/questions/25401981/how-to-display-text-in-android-canvas-shapedrawable-with-rectshape)? – LOG_TAG Aug 20 '14 at 10:51
  • 1
    and for setting text size in `dp` you can use as [this](http://stackoverflow.com/questions/3061930/how-to-set-unit-for-paint-settextsize) – S.M.Mousavi May 31 '16 at 13:46
  • It's important to reset the style to FILL, otherwise it may stroke your text (with potentially really thick lines) and look really bold and ugly. – Chase Roberts Jul 28 '16 at 17:59
  • Here, In the drawText("Some Text",10,25,paint); it means left margin is 10 and top margin is 25. am I right? – Prince Dholakiya Jul 04 '19 at 06:07
  • @PrinceDholakiya that's the x and y.. indicating the top left position of the text. – glennmark Dec 22 '20 at 03:13
47

It should be noted that the documentation recommends using a Layout rather than Canvas.drawText directly. My full answer about using a StaticLayout is here, but I will provide a summary below.

String text = "This is some text.";

TextPaint textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
textPaint.setColor(0xFF000000);

int width = (int) textPaint.measureText(text);
StaticLayout staticLayout = new StaticLayout(text, textPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
staticLayout.draw(canvas);

Here is a fuller example in the context of a custom view:

enter image description here

public class MyView extends View {

    String mText = "This is some text.";
    TextPaint mTextPaint;
    StaticLayout mStaticLayout;

    // use this constructor if creating MyView programmatically
    public MyView(Context context) {
        super(context);
        initLabelView();
    }

    // this constructor is used when created from xml
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();
    }

    private void initLabelView() {
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
        mTextPaint.setColor(0xFF000000);

        // default to a single line of text
        int width = (int) mTextPaint.measureText(mText);
        mStaticLayout = new StaticLayout(mText, mTextPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);

        // New API alternate
        //
        // StaticLayout.Builder builder = StaticLayout.Builder.obtain(mText, 0, mText.length(), mTextPaint, width)
        //        .setAlignment(Layout.Alignment.ALIGN_NORMAL)
        //        .setLineSpacing(1, 0) // multiplier, add
        //        .setIncludePad(false);
        // mStaticLayout = builder.build();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Tell the parent layout how big this view would like to be
        // but still respect any requirements (measure specs) that are passed down.

        // determine the width
        int width;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthRequirement = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthRequirement;
        } else {
            width = mStaticLayout.getWidth() + getPaddingLeft() + getPaddingRight();
            if (widthMode == MeasureSpec.AT_MOST) {
                if (width > widthRequirement) {
                    width = widthRequirement;
                    // too long for a single line so relayout as multiline
                    mStaticLayout = new StaticLayout(mText, mTextPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
                }
            }
        }

        // determine the height
        int height;
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightRequirement = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightRequirement;
        } else {
            height = mStaticLayout.getHeight() + getPaddingTop() + getPaddingBottom();
            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(height, heightRequirement);
            }
        }

        // Required call: set width and height
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // do as little as possible inside onDraw to improve performance

        // draw the text on the canvas after adjusting for padding
        canvas.save();
        canvas.translate(getPaddingLeft(), getPaddingTop());
        mStaticLayout.draw(canvas);
        canvas.restore();
    }
}
Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393