Comment obtenir la largeur de la chaîne sur Android?

Réponses:

202

Vous pouvez utiliser la getTextBounds(String text, int start, int end, Rect bounds)méthode d'un objet Paint. Vous pouvez soit utiliser l'objet de peinture fourni par un, TextViewsoit en créer un vous-même avec l'apparence de texte souhaitée.

En utilisant une vue de texte, vous pouvez effectuer les opérations suivantes:

Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
int width = bounds.width();
Franc
la source
5
@Frank: Que faire si la chaîne est une chaîne étendue?
Ashwin
Très bonne réponse. En passant, le résultat sera plus précis si call textView.setTextSize().
li2
81

Si vous avez juste besoin de la largeur, vous pouvez utiliser:

float width = paint.measureText(string);

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

SharkAlley
la source
4
De plus, si vous souhaitez mesurer le texte avec une certaine taille de police, vous pouvez utiliser TextPaint paint = new TextPaint(); paint.setTextSize(textSize);. textSizeest en pixels.
Nathan Reline le
Et pour prendre de la hauteur?
Prince
19

Il existe deux mesures de largeur différentes pour un texte. L'un est le nombre de pixels qui ont été dessinés dans la largeur, l'autre est le nombre de «pixels» que le curseur doit avancer après avoir dessiné le texte.

paint.measureText et paint.getTextWidths renvoie le nombre de pixels (en float) que le curseur doit avancer après avoir dessiné la chaîne donnée. Pour le nombre de pixels peints, utilisez paint.getTextBounds comme mentionné dans une autre réponse. Je crois que cela s'appelle «Advance» de la police.

Pour certaines polices, ces deux mesures diffèrent (beaucoup), par exemple la police Black Chancery a des lettres qui dépassent les autres lettres (se chevauchant) - voir le «L» majuscule. Utilisez paint.getTextBounds comme mentionné dans une autre réponse pour obtenir des pixels peints.

Arberg
la source
6

J'ai mesuré la largeur de cette façon:

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());

Cela vous aiderait.

Hiren Patel
la source
3

Très probablement, vous voulez connaître les dimensions peintes pour une chaîne de texte donnée avec une police donnée (c'est-à-dire une police particulière Typefacetelle que la famille de polices «sans-serif» avec un style BOLD_ITALIC, et une taille particulière en sp ou px).

Plutôt que de gonfler un plein souffle TextView, vous pouvez aller au niveau inférieur et travailler avec un Paintobjet directement pour du texte sur une seule ligne , par exemple:

// 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());



Pour le texte multi-lignes ou fractionné ( SpannedString), envisagez d'utiliser a StaticLayout, dans lequel vous indiquez la largeur et dérivez la hauteur. Pour une réponse très élaborée sur la mesure et le dessin de texte sur un canevas dans une vue personnalisée, voir: https://stackoverflow.com/a/41779935/954643

Il convient également de noter la réponse de @ arberg ci-dessous à propos des pixels peints par rapport à la largeur d'avance ("nombre de pixels (en flottant) que le curseur doit avancer après avoir dessiné la chaîne donnée"), au cas où vous auriez besoin de gérer cela.

qix
la source
2

J'aimerais partager un meilleur moyen (plus polyvalent que la réponse actuellement acceptée) d'obtenir la largeur exacte d'un texte dessiné ( String) avec l'utilisation de la classe statique StaticLayout:

StaticLayout.getDesiredWidth(text, textPaint))

cette méthode est plus précise que textView.getTextBounds(), puisque vous pouvez calculer la largeur d'une seule ligne dans une multiligne TextView, ou que vous ne pouvez pas l'utiliser TextViewpour commencer (par exemple dans une Viewimplémentation personnalisée ).

Cette méthode est similaire à textPaint.measureText(text), mais elle semble être plus précise dans de rares cas.

Serj Ardovic
la source