5Answers
  • 12
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

How to put text in a drawable?

I'm trying to create a drawable on the fly to use as a background for a custom linearlayout. It needs to have hash marks and such (no big deal), but also have numbers labeling what the hash marks are (like a ruler). I know I can just create text elements and put them inside the linearlayout and just have the hash marks in the drawable, but I'm hoping to have them inside the drawable as well, so I don't have to do measurement calculations twice.

Here is a brief example of a TextDrawable which works like a normal drawable but lets you specify text as the only constructor variable:

public class TextDrawable extends Drawable {

    private final String text;
    private final Paint paint;

    public TextDrawable(String text) {

        this.text = text;

        this.paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setTextSize(22f);
        paint.setAntiAlias(true);
        paint.setFakeBoldText(true);
        paint.setShadowLayer(6f, 0, 0, Color.BLACK);
        paint.setStyle(Paint.Style.FILL);
        paint.setTextAlign(Paint.Align.LEFT);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawText(text, 0, 0, paint);
    }

    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        paint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}
  • 96
Reply Report
      • 2
    • it works fine the only problem is text displayed wide.i am drawing text at (x,y) according to progress. where x = progress*seekBar.getWidth()/seekBar.getMax() and y = seekBar.getHeight()/2. can you please tell me where is my mistake to calculate the x,y co-ordinates.
    • ok it works perfect. that was my mistake. i have putted padding(left and right) of seek bar.Thanks plowman.

I've read the book "Professional Android 2 Application Development" (by Reto Meier). Amongst others, it contains an example project where you create a simple compass application where you "draw" text, markers etc.

The brief explanation is that you create a class that extends the android.view.View class and overrides the onDraw(Canvas) method.

All the source code form the book is available for download here: http://www.wrox.com/WileyCDA/WroxTitle/Professional-Android-2-Application-Development.productCd-0470565527,descCd-DOWNLOAD.html. If you download the code and look inside the project named "Chapter 4 Compass", I believe you would find what you're looking for :)

  • 14
Reply Report

Looking at Plowman's answer and trying to adjust it to my needs I stumpled upon a Class that is used for Camera in this link

Here is the code from the TextDrawable Class. Looks pretty simillar with Plowmans but for me works better:

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;

public class TextDrawable extends Drawable {
    private static final int DEFAULT_COLOR = Color.WHITE;
    private static final int DEFAULT_TEXTSIZE = 15;
    private Paint mPaint;
    private CharSequence mText;
    private int mIntrinsicWidth;
    private int mIntrinsicHeight;

    public TextDrawable(Resources res, CharSequence text) {
        mText = text;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(DEFAULT_COLOR);
        mPaint.setTextAlign(Align.CENTER);
        float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                DEFAULT_TEXTSIZE, res.getDisplayMetrics());
        mPaint.setTextSize(textSize);
        mIntrinsicWidth = (int) (mPaint.measureText(mText, 0, mText.length()) + .5);
        mIntrinsicHeight = mPaint.getFontMetricsInt(null);
    }
    @Override
    public void draw(Canvas canvas) {
        Rect bounds = getBounds();
        canvas.drawText(mText, 0, mText.length(),
                bounds.centerX(), bounds.centerY(), mPaint);
    }
    @Override
    public int getOpacity() {
        return mPaint.getAlpha();
    }
    @Override
    public int getIntrinsicWidth() {
        return mIntrinsicWidth;
    }
    @Override
    public int getIntrinsicHeight() {
        return mIntrinsicHeight;
    }
    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }
    @Override
    public void setColorFilter(ColorFilter filter) {
        mPaint.setColorFilter(filter);
    }
}
  • 7
Reply Report

To answer the comments above regarding how to center the text:

mPaint.textAlign = Align.CENTER
...
// Centering for mixed case letters
canvas.drawText(mText, 0, mText.length,
        bounds.centerX().toFloat(), bounds.centerY().toFloat() - ((mPaint.descent() + mPaint.ascent()) / 2), mPaint)

// Centering for all uppercase letters
canvas.drawText(mText, 0, mText.length,
            bounds.centerX().toFloat(), bounds.centerY().toFloat() - mPaint.ascent() / 2, mPaint)
  • 3
Reply Report

This allows you to put any View in a Drawable, including a TextView. You can even use styles in your XML layout.

public class ViewDrawable extends Drawable {
    final View mView;

    public ViewDrawable(final Context context, final @LayoutRes int layoutId) {
        this(LayoutInflater.from(context).inflate(layoutId, null));
    }

    public ViewDrawable(final @NonNull View view) {
        mView = view;
    }

    public View getView() {
        return mView;
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        super.setBounds(left, top, right, bottom);
        final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(right - left, View.MeasureSpec.EXACTLY);
        final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY);
        mView.measure(widthMeasureSpec, heightMeasureSpec);
        mView.layout(left, top, right, bottom);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        mView.draw(canvas);
    }

    @Override
    public void setAlpha(int alpha) {
        mView.setAlpha(alpha/255f);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return PixelFormat.UNKNOWN;
    }
}
  • 1
Reply Report