Jak uzyskać szerokość ciągu na Androidzie?


Odpowiedzi:


203

Możesz użyć getTextBounds(String text, int start, int end, Rect bounds)metody obiektu Paint. Możesz użyć obiektu malowania dostarczonego przez a TextViewlub zbudować go samodzielnie z pożądanym wyglądem tekstu.

Korzystając z widoku tekstowego, możesz wykonać następujące czynności:

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: A co, jeśli łańcuch jest ciągiem łączonym?
— Ashwin

Świetna odpowiedź. Nawiasem mówiąc, wynik będzie dokładniejszy, jeśli zadzwonisz textView.setTextSize().
— li2


19

Istnieją dwie różne miary szerokości tekstu. Jedna to liczba pikseli, które zostały narysowane na szerokość, druga to liczba „pikseli”, które należy przesunąć kursor po narysowaniu tekstu.

paint.measureText i paint.getTextWidths zwracają liczbę pikseli (w liczbie zmiennoprzecinkowej), o którą kursor powinien zostać przesunięty po narysowaniu danego ciągu. Aby określić liczbę pomalowanych pikseli, użyj funkcji paint.getTextBounds, jak wspomniano w innej odpowiedzi. Uważam, że nazywa się to „Advance” czcionki.

W przypadku niektórych czcionek te dwa wymiary różnią się (bardzo), na przykład czcionka Black Chancery ma litery, które wykraczają poza inne litery (nakładają się) - patrz duże „L”. Użyj paint.getTextBounds, jak wspomniano w innej odpowiedzi, aby pomalować piksele.


6

Zmierzyłem szerokość w ten sposób:

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

To by ci pomogło.


3

Najprawdopodobniej chcesz poznać pomalowane wymiary dla danego ciągu tekstu z określoną czcionką (tj. Konkretną Typeface rodziną czcionek „sans-serif” ze stylem BOLD_ITALIC i określonym rozmiarem w sp lub px).

Zamiast nadmuchać pełnowymiarowy TextView, możesz zejść niżej i pracować z Paintobiektem bezpośrednio dla tekstu jednowierszowego , na przykład:

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



W przypadku tekstu wielowierszowego lub łączonego ( SpannedString) rozważ użycie znaku StaticLayout, w którym podajesz szerokość i uzyskujesz wysokość. Aby uzyskać bardzo szczegółową odpowiedź na temat mierzenia i rysowania tekstu na płótnie w niestandardowym widoku, patrz: https://stackoverflow.com/a/41779935/954643

Warto również zwrócić uwagę na poniższą odpowiedź @ arberga na temat pomalowanych pikseli w porównaniu z szerokością wyprzedzenia ("liczba pikseli (w liczbie zmiennoprzecinkowej), o którą kursor powinien zostać przesunięty po narysowaniu danego ciągu"), na wypadek gdybyś musiał sobie z tym poradzić.


2

Chciałbym podzielić się lepszym (bardziej wszechstronnym niż obecnie akceptowana odpowiedź) sposobem uzyskania dokładnej szerokości rysowanego tekstu ( String) przy użyciu klasy statycznej StaticLayout:

StaticLayout.getDesiredWidth(text, textPaint))

ta metoda jest dokładniejsza niż textView.getTextBounds(), ponieważ można obliczyć szerokość pojedynczej linii w multilinii TextViewlub nie używać jej TextViewna początku (na przykład w niestandardowej Viewimplementacji).

Ten sposób jest podobny textPaint.measureText(text), jednak w rzadkich przypadkach wydaje się być dokładniejszy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.