42 votes

Comment mettre du texte dans un drawable ?

J'essaie de créer à la volée un tableau à utiliser comme arrière-plan pour une mise en page linéaire personnalisée. Il doit comporter des marques de hachage et autres (ce qui n'est pas très important), mais aussi des chiffres indiquant la position des marques de hachage (comme une règle). Je sais que je peux me contenter de créer des éléments de texte et de les placer à l'intérieur de la structure linéaire, et d'avoir les marques de hachage dans la table à dessin, mais j'espère les avoir également à l'intérieur de la table à dessin, pour ne pas avoir à faire deux fois les calculs de mesure.

102voto

plowman Points 5106

Voici un bref exemple d'une TextDrawable qui fonctionne comme un dessinable normal mais vous permet de spécifier le texte comme seule variable de construction :

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

16voto

Nailuj Points 7283

J'ai lu le livre "Professional Android 2 Application Development" (de Reto Meier). Il contient, entre autres, un projet d'exemple où l'on crée une application simple de boussole où l'on "dessine" du texte, des marqueurs, etc.

La brève explication est la suivante : vous créez une classe qui étend la classe android.view.View et remplace la classe onDraw(Canvas) méthode.

Tout le code source du livre est disponible pour le téléchargement ici : http://www.wrox.com/WileyCDA/WroxTitle/Professional-Android-2-Application-Development.productCd-0470565527,descCd-DOWNLOAD.html . Si vous téléchargez le code et regardez dans le projet nommé "Chapitre 4 Compass", je pense que vous trouverez ce que vous cherchez :)

12voto

Jimmy Kane Points 3808

En regardant la réponse de Plowman et en essayant de l'adapter à mes besoins, je suis tombé sur une classe qui est utilisée pour Appareil photo dans ce lien

Voici le code de la Classe TextDrawable . Il ressemble beaucoup à celui de Plowmans, mais pour moi, il fonctionne mieux :

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

6voto

user2241362 Points 63

Pour répondre aux commentaires ci-dessus concernant la façon de centrer le texte :

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)

4voto

Dustin Points 286

Cela vous permet de placer n'importe quelle vue dans un Drawable, y compris un TextView. Vous pouvez même utiliser des styles dans votre mise en page XML.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X