Come ottenere la larghezza della stringa su Android?


Risposte:


202

Puoi usare il getTextBounds(String text, int start, int end, Rect bounds)metodo di un oggetto Paint. Puoi utilizzare l'oggetto pittura fornito da a TextViewoppure crearne uno tu stesso con l'aspetto del testo desiderato.

Utilizzando una visualizzazione di testo puoi fare quanto segue:

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

5
@ Frank: cosa succede se la stringa è una stringa con spanning?
Ashwin

Bella risposta. A proposito, il risultato sarà più accurato se si chiama textView.setTextSize().
li2


19

Ci sono due diverse misure di larghezza per un testo. Uno è il numero di pixel che sono stati disegnati in larghezza, l'altro è il numero di "pixel" in cui il cursore dovrebbe essere spostato dopo aver disegnato il testo.

paint.measureText e paint.getTextWidths restituiscono il numero di pixel (in float) a cui il cursore dovrebbe avanzare dopo aver disegnato la stringa data. Per il numero di pixel dipinti usa paint.getTextBounds come menzionato in un'altra risposta. Credo che questo si chiami "Advance" del font.

Per alcuni caratteri queste due misure differiscono (molto), ad esempio il carattere Black Chancery ha lettere che si estendono oltre le altre lettere (sovrapposte) - vedere la "L" maiuscola. Usa paint.getTextBounds come menzionato in un'altra risposta per far dipingere i pixel.


6

Ho misurato la larghezza in questo modo:

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

Questo ti aiuterebbe.


3

Molto probabilmente vuoi conoscere le dimensioni dipinte per una data stringa di testo con un dato carattere (cioè un particolare Typefacecome la famiglia di caratteri "sans-serif" con uno stile BOLD_ITALIC e una dimensione particolare in sp o px).

Piuttosto che gonfiare un vero e proprio TextView, puoi andare di livello inferiore e lavorare Paintdirettamente con un oggetto per il testo a riga singola , ad esempio:

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



Per il testo su più righe o con spanning ( SpannedString), prendi in considerazione l'utilizzo di a StaticLayout, in cui fornisci la larghezza e derivi l'altezza. Per una risposta molto elaborata sulla misurazione e il disegno di testo su una tela in una visualizzazione personalizzata, vedere: https://stackoverflow.com/a/41779935/954643

Vale anche la pena notare la risposta di @ arberg di seguito sui pixel dipinti rispetto alla larghezza avanzata ("numero di pixel (in float) a cui il cursore dovrebbe essere avanzato dopo aver disegnato la stringa data"), nel caso in cui sia necessario affrontarlo.


2

Vorrei condividere un modo migliore (più versatile dell'attuale risposta accettata) per ottenere la larghezza esatta di un testo disegnato ( String) con l'uso della classe statica StaticLayout:

StaticLayout.getDesiredWidth(text, textPaint))

questo metodo è più accurato di textView.getTextBounds(), poiché puoi calcolare la larghezza di una singola riga in una multilinea TextViewo potresti non utilizzarlo TextViewper iniziare (ad esempio in Viewun'implementazione personalizzata ).

Questo modo è simile a textPaint.measureText(text), tuttavia sembra essere più accurato in rari casi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.