จัดกึ่งกลางด้วยPaint.getTextBounds () :
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ไม่ได้หมายความว่าจุดอ้างอิงของข้อความอยู่กึ่งกลางแนวตั้ง จุดอ้างอิงจะอยู่บนเส้นฐานเสมอ ดังนั้นทำไมไม่ใช้Paint.Align.LEFT ? คุณต้องคำนวณจุดอ้างอิงต่อไป
Paint.descent ()มีข้อเสียคือไม่พิจารณาข้อความจริง Paint.descent ()ดึงค่าเดียวกันโดยไม่คำนึงว่าข้อความนั้นประกอบด้วยตัวอักษรที่มีการแทรกหรือไม่ นั่นเป็นเหตุผลที่ฉันใช้r.bottomแทน
ฉันมีปัญหาบางอย่างกับCanvas.getHeight ()ถ้า API <16 นั่นเป็นเหตุผลที่ฉันใช้Canvas.getClipBounds (Rect)แทน (อย่าใช้Canvas.getClipBounds (). getHeight ()ตามที่จัดสรรหน่วยความจำสำหรับRect )
สำหรับเหตุผลของประสิทธิภาพการทำงานคุณควรจัดสรรวัตถุก่อนที่พวกเขาจะใช้ในOnDraw () ในฐานะที่เป็นdrawCenter ()จะถูกเรียกภายในonDraw ()วัตถุRect rถูกจัดสรรล่วงหน้าเป็นเขตข้อมูลที่นี่
ฉันพยายามใส่รหัสของคำตอบสองข้อแรกลงในรหัสของฉันเอง (สิงหาคม 2015) และสร้างภาพหน้าจอเพื่อเปรียบเทียบผลลัพธ์:
ข้อความควรอยู่กึ่งกลางภายในสี่เหลี่ยมเติมสีแดง รหัสของฉันสร้างข้อความสีขาวส่วนอีกสองรหัสจะสร้างข้อความสีเทาทั้งหมด (จริง ๆ แล้วเป็นรหัสเดียวกันซ้อนทับกัน) ข้อความสีเทาต่ำเกินไปเล็กน้อยและอยู่ทางด้านขวาสองรายการ
นี่คือวิธีที่ฉันทำแบบทดสอบ:
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);
}
}