回答:
何について)(paint.getTextBounds(オブジェクトメソッド)
必要に応じて、高さを測定するさまざまな方法があります。
少量の固定テキストを正確に中央揃えするようなことをしている場合は、おそらく必要ですgetTextBounds
。あなたはこのように外接する長方形を得ることができます
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();
次の画像からわかるように、ストリングが異なると高さが異なります(赤で表示)。
これらの異なる高さは、テキストが何であっても一定の高さだけが必要な場合に不利になることがあります。次のセクションを参照してください。
フォントメトリックからフォントの高さを計算できます。特定のテキスト文字列ではなく、フォントから取得されるため、高さは常に同じです。
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;
ベースラインは、テキストが置かれる行です。ディセントは通常、キャラクターがラインの下に行く最も遠いところにあり、アセントは一般的にキャラクターがラインの上にくる最も遠いところにあります。高さを取得するには、それが負の値であるため、アセントを引く必要があります。(ベースラインは画面であり、画面y=0
をy
減少させます。)
次の画像を見てください。両方のストリングの高さは234.375
です。
テキストの高さだけでなく、行の高さが必要な場合は、次のようにします。
float height = fm.bottom - fm.top + fm.leading; // 265.4297
これらはラインのbottom
and top
です。先頭(行間)は通常ゼロですが、とにかく追加する必要があります。
上の画像はこのプロジェクトからのものです。フォントメトリックがどのように機能するかを確認するために、これをいじってみてください。
複数行のテキストの高さを測定するには、を使用する必要がありStaticLayout
ます。この回答で少し詳しく説明しましたが、この高さを取得する基本的な方法は次のとおりです。
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);
int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);
float height = myStaticLayout.getHeight();
getTextSize()
は、フォントサイズを(sp
単位ではなく)ピクセル単位で示します。@androiddeveloper
@brampの答えは正しいです-部分的に、計算された境界は、暗黙の開始座標0、0でテキストを完全に含む最小の長方形になることは言及されていません。
つまり、たとえば「Py」の高さは「py」、「hi」、「oi」、「aw」の高さとは異なります。これは、ピクセル単位で高さが異なるためです。
これは、決して古典的なJavaのFontMetricsと同等ではありません。
テキストの幅はそれほど問題ではありませんが、高さは問題ではありません。
特に、描画されたテキストを垂直方向に中央揃えにする必要がある場合は、描画するテキストを使用する代わりに、テキスト "a"(引用符なし)の境界を取得してみてください。私のために働く...
これが私の意味です:
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(textSize);
Rect bounds = new Rect();
paint.getTextBounds("a", 0, 1, bounds);
buffer.drawText(this.myText, canvasWidth >> 1, (canvasHeight + bounds.height()) >> 1, paint);
// remember x >> 1 is equivalent to x / 2, but works much much faster
テキストを垂直方向に中央揃えするとは、境界の長方形を垂直方向に中央揃えにすることです。これは、テキスト(大文字、長い文字など)によって異なります。しかし、実際にやりたいのは、レンダリングされたテキストのベースラインを揃えて、高さや溝が表示されないようにすることです。したがって、最小の文字の中心(たとえば "a")がわかっている限り、その配置を残りのテキストに再利用できます。これにより、すべてのテキストが中央揃えになり、ベースライン揃えになります。
x >> 1
ていません。そのためだけに賛成:)
x / 2
、それを表示して最適化しますx >> 1
x / 2
は、Chrisのコメントを考慮すると、コードを読むときにはるかに友好的です。
buffer
この例には何がありますか?それはメソッドにcanvas
渡されdraw(Canvas)
ますか?
android.text.StaticLayout
クラスを使用して必要な境界を指定し、を呼び出すことができますgetHeight()
。draw(Canvas)
メソッドを呼び出すことにより、テキスト(レイアウトに含まれる)を描画できます。
getTextSize()メソッドを使用すると、Paintオブジェクトのテキストサイズを簡単に取得できます。例えば:
Paint mTextPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
//use densityMultiplier to take into account different pixel densities
final float densityMultiplier = getContext().getResources()
.getDisplayMetrics().density;
mTextPaint.setTextSize(24.0f*densityMultiplier);
//...
float size = mTextPaint.getTextSize();
24.0f
から来たのですか?
それでも問題が解決しない場合は、これが私のコードです。
正方形(幅=高さ)のカスタムビューがあり、それに文字を割り当てたいです。onDraw()
文字の高さを取得する方法を示していますが、使用していません。画面中央にキャラクターが表示されます。
public class SideBarPointer extends View {
private static final String TAG = "SideBarPointer";
private Context context;
private String label = "";
private int width;
private int height;
public SideBarPointer(Context context) {
super(context);
this.context = context;
init();
}
public SideBarPointer(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
public SideBarPointer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init();
}
private void init() {
// setBackgroundColor(0x64FF0000);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
height = this.getMeasuredHeight();
width = this.getMeasuredWidth();
setMeasuredDimension(width, width);
}
protected void onDraw(Canvas canvas) {
float mDensity = context.getResources().getDisplayMetrics().density;
float mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
Paint previewPaint = new Paint();
previewPaint.setColor(0x0C2727);
previewPaint.setAlpha(200);
previewPaint.setAntiAlias(true);
Paint previewTextPaint = new Paint();
previewTextPaint.setColor(Color.WHITE);
previewTextPaint.setAntiAlias(true);
previewTextPaint.setTextSize(90 * mScaledDensity);
previewTextPaint.setShadowLayer(5, 1, 2, Color.argb(255, 87, 87, 87));
float previewTextWidth = previewTextPaint.measureText(label);
// float previewTextHeight = previewTextPaint.descent() - previewTextPaint.ascent();
RectF previewRect = new RectF(0, 0, width, width);
canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
canvas.drawText(label, (width - previewTextWidth)/2, previewRect.top - previewTextPaint.ascent(), previewTextPaint);
super.onDraw(canvas);
}
public void setLabel(String label) {
this.label = label;
Log.e(TAG, "Label: " + label);
this.invalidate();
}
}