Mit Paint.getTextBounds () zentrieren :
private Rect r = new Rect();
private void drawCenter(Canvas canvas, Paint paint, String text) {
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
paint.setTextAlign(Paint.Align.LEFT);
paint.getTextBounds(text, 0, text.length(), r);
float x = cWidth / 2f - r.width() / 2f - r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
canvas.drawText(text, x, y, paint);
}
Paint.Align.CENTER bedeutet nicht, dass der Referenzpunkt des Textes vertikal zentriert ist. Der Referenzpunkt liegt immer auf der Grundlinie. Warum also nicht Paint.Align.LEFT verwenden ? Sie müssen den Referenzpunkt trotzdem berechnen.
Paint.descent () hat den Nachteil, dass der echte Text nicht berücksichtigt wird. Paint.descent () ruft denselben Wert ab, unabhängig davon, ob der Text Buchstaben mit Abfahrten enthält oder nicht. Deshalb benutze ich stattdessen r.bottom .
Ich hatte einige Probleme mit Canvas.getHeight (), wenn API <16. Deshalb verwende ich stattdessen Canvas.getClipBounds (Rect) . (Nicht verwenden Canvas.getClipBounds (). GetHeight () , wie es Speicher für einen zuordnet Rect .)
Aus Leistungsgründen sollten Sie Objekte zuweisen, bevor sie in onDraw () verwendet werden . Wie drawCenter () wird innerhalb von aufgerufen werden OnDraw () das Objekt Rect r wird als Feld hier vorbelegt.
Ich habe versucht, den Code der beiden Top-Antworten in meinen eigenen Code einzufügen (August 2015) und einen Screenshot erstellt, um die Ergebnisse zu vergleichen:
Der Text sollte innerhalb des rot gefüllten Rechtecks zentriert sein. Mein Code erzeugt den weißen Text, die anderen beiden Codes erzeugen insgesamt den grauen Text (sie sind tatsächlich gleich und überlappen sich). Der graue Text ist etwas zu niedrig und zwei viel rechts.
So habe ich den Test gemacht:
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
class MyView extends View {
private static String LABEL = "long";
private static float TEXT_HEIGHT_RATIO = 0.82f;
private FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(0, 0);
private Rect r = new Rect();
private Paint paint = new Paint();
private Paint rectPaint = new Paint();
public MyView(Context context) {
super(context);
}
private void drawTextBounds(Canvas canvas, Rect rect, int x, int y) {
rectPaint.setColor(Color.rgb(0, 0, 0));
rectPaint.setStyle(Paint.Style.STROKE);
rectPaint.setStrokeWidth(3f);
rect.offset(x, y);
canvas.drawRect(rect, rectPaint);
}
// andreas1724 (white color):
private void draw1(Canvas canvas, Paint paint, String text) {
paint.setTextAlign(Paint.Align.LEFT);
paint.setColor(Color.rgb(255, 255, 255));
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
paint.getTextBounds(text, 0, text.length(), r);
float x = cWidth / 2f - r.width() / 2f - r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
canvas.drawText(text, x, y, paint);
drawTextBounds(canvas, r, (int) x, (int) y);
}
// Arun George (light green color):
private void draw2(Canvas canvas, Paint textPaint, String text) {
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setColor(Color.argb(100, 0, 255, 0));
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2));
canvas.drawText(text, xPos, yPos, textPaint);
}
// VinceStyling (light blue color):
private void draw3(Canvas yourCanvas, Paint mPaint, String pageTitle) {
mPaint.setTextAlign(Paint.Align.LEFT);
mPaint.setColor(Color.argb(100, 0, 0, 255));
r = yourCanvas.getClipBounds();
RectF bounds = new RectF(r);
bounds.right = mPaint.measureText(pageTitle, 0, pageTitle.length());
bounds.bottom = mPaint.descent() - mPaint.ascent();
bounds.left += (r.width() - bounds.right) / 2.0f;
bounds.top += (r.height() - bounds.bottom) / 2.0f;
yourCanvas.drawText(pageTitle, bounds.left, bounds.top - mPaint.ascent(), mPaint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int margin = 10;
int width = w - 2 * margin;
int height = h - 2 * margin;
params.width = width;
params.height = height;
params.leftMargin = margin;
params.topMargin = margin;
setLayoutParams(params);
paint.setTextSize(height * TEXT_HEIGHT_RATIO);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.create(Typeface.SERIF, Typeface.BOLD_ITALIC));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.rgb(255, 0, 0));
draw1(canvas, paint, LABEL);
draw2(canvas, paint, LABEL);
draw3(canvas, paint, LABEL);
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
FrameLayout container = new FrameLayout(this);
container.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
container.addView(new MyView(this));
setContentView(container);
}
}