web-dev-qa-db-ja.com

Androidで文字列の幅を取得する方法は?

できれば高さも取得したいです。

92
Mikael Lindlöf

Paintオブジェクトの getTextBounds(String text, int start, int end, Rect bounds) メソッドを使用できます。 TextViewで提供されるPaintオブジェクトを使用するか、希望するテキストの外観で自分でビルドすることができます。

Textviewを使用すると、次のことができます。

Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
int width = bounds.width();
190
Frank

幅だけが必要な場合は、次を使用できます。

float width = Paint.measureText(string);

http://developer.Android.com/reference/Android/graphics/Paint.html#measureText(Java.lang.String)

71
SharkAlley

テキストには2つの異なる幅の尺度があります。 1つは幅に描画されたピクセル数、もう1つはテキストを描画した後にカーソルを進める必要がある「ピクセル」数です。

Paint.measureTextおよびPaint.getTextWidthsはピクセル数( float)指定された文字列を描画した後、カーソルを進めます。ペイントされたピクセル数については、他の回答で述べたようにPaint.getTextBoundsを使用します。これはフォントの「アドバンス」と呼ばれます。

一部のフォントでは、これら2つの測定値が異なります(alot)。たとえば、フォント Black Chancery は、他の文字を超えて(重複する)文字を持ちます-大文字の「L」を参照してください。 Paint.getTextBoundsを使用して、他の回答で述べたように、ピクセルをペイントします。

18
arberg

私はこの方法で幅を測定しました:

String str ="Hiren Patel";

Paint paint = new Paint();
Paint.setTextSize(20);
Typeface typeface = Typeface.createFromAsset(getAssets(), "Helvetica.ttf");
Paint.setTypeface(typeface);
Paint.setColor(Color.BLACK);
Paint.setStyle(Paint.Style.FILL);
Rect result = new Rect();
Paint.getTextBounds(str, 0, str.length(), result);

Log.i("Text dimensions", "Width: "+result.width());

これはあなたを助けるでしょう。

5
Hiren Patel

おそらく、特定のフォント(つまり、BOLD_ITALICスタイルの「sans-serif」フォントファミリなどの特定の Typeface )を使用して、特定のテキスト文字列のペイントされた寸法を知りたいと思うでしょう。 、およびspまたはpxの特定のサイズ)。

本格的なTextViewを拡張するのではなく、single-の下位レベルに移動して Paint オブジェクトを直接操作できます。 lineテキスト、たとえば:

// Maybe you want to construct a (possibly static) member for repeated computations
Paint paint = new Paint();

// You can load a font family from an asset, and then pick a specific style:
//Typeface plain = Typeface.createFromAsset(assetManager, pathToFont); 
//Typeface bold = Typeface.create(plain, Typeface.DEFAULT_BOLD);
// Or just reference a system font:
Paint.setTypeface(Typeface.create("sans-serif",Typeface.BOLD));

// Don't forget to specify your target font size. You can load from a resource:
//float scaledSizeInPixels = context.getResources().getDimensionPixelSize(R.dimen.mediumFontSize);
// Or just compute it fully in code:
int spSize = 18;
float scaledSizeInPixels = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP,
            spSize,
            context.getResources().getDisplayMetrics());
Paint.setTextSize(scaledSizeInPixels);

// Now compute!
Rect bounds = new Rect();
String myString = "Some string to measure";
Paint.getTextBounds(myString, 0, myString.length(), bounds);
Log.d(TAG, "width: " + bounds.width() + " height: " + bounds.height());

複数行またはスパンテキストSpannedString)の場合、StaticLayoutを使用することを検討してください。高さを導き出します。それを行うカスタムビューでキャンバスにテキストを測定して描画することに関する非常に手の込んだ回答については、以下を参照してください。 https://stackoverflow.com/a/41779935/95464

また、対処する必要がある場合に備えて、ペイントされたピクセルとアドバンス幅(「特定の文字列を描画した後にカーソルを進める必要があるピクセル数(フロート)」)について@arbergの返信に注目してください。

1
qix

より良い方法を共有したい(現在受け入れられている答えよりも汎用性が高い)静的クラスStringを使用して、描画されたテキスト(StaticLayout)の正確な幅を取得する

StaticLayout.getDesiredWidth(text, textPaint))

このメソッドはtextView.getTextBounds()よりも正確です。複数行のTextViewの単一行の幅を計算できるか、最初にTextViewを使用しない場合があるためです(たとえば、カスタムView実装で)。

この方法はtextPaint.measureText(text)と似ていますが、まれなケースではより正確であるようです。

1
Serj Ardovic