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.
Réponses
Trop de publicités?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;
}
}
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 :)
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);
}
}
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)
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;
}
}