Làm cách nào để lấy độ rộng chuỗi trên Android?


Câu trả lời:


201

Bạn có thể sử dụng getTextBounds(String text, int start, int end, Rect bounds)phương thức của một đối tượng Paint. Bạn có thể sử dụng đối tượng sơn do a cung cấp TextViewhoặc tự tạo đối tượng với giao diện văn bản mong muốn.

Sử dụng Textview bạn có thể làm như sau:

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: Điều gì sẽ xảy ra nếu Chuỗi là một chuỗi kéo dài?
Ashwin

Câu trả lời chính xác. Nhân tiện, kết quả sẽ chính xác hơn nếu gọi textView.setTextSize().
li2


19

Có hai thước đo chiều rộng khác nhau cho một văn bản. Một là số pixel đã được vẽ theo chiều rộng, một là số 'pixel' mà con trỏ sẽ được nâng cao sau khi vẽ văn bản.

paint.measureTextpaint.getTextWidths trả về số pixel (trong float) mà con trỏ sẽ được nâng cao sau khi vẽ chuỗi đã cho. Đối với số lượng pixel được sơn, hãy sử dụng paint.getTextBounds như đã đề cập trong câu trả lời khác. Tôi tin rằng đây được gọi là 'Advance' của phông chữ.

Đối với một số phông chữ, hai phép đo này khác nhau (rất nhiều), ví dụ: phông chữ Black Chancery có các chữ cái kéo dài qua các chữ cái khác (chồng chéo) - xem chữ 'L' viết hoa. Sử dụng paint.getTextBounds như đã đề cập trong câu trả lời khác để tô các pixel.


6

Tôi đã đo chiều rộng theo cách này:

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

Điều này sẽ giúp bạn.


3

Nhiều khả năng bạn muốn biết các kích thước được tô cho một chuỗi văn bản nhất định với một phông chữ nhất định (tức là một phông chữ cụ thể Typefacechẳng hạn như họ phông chữ “sans-serif” với kiểu BOLD_ITALIC và kích thước cụ thể bằng sp hoặc px).

Thay vì thổi phồng toàn bộ TextView, bạn có thể đi xuống cấp thấp hơn và làm việc với một Paintđối tượng trực tiếp cho văn bản một dòng , ví dụ:

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



Đối với văn bản có nhiều dòng hoặc kéo dài ( SpannedString), hãy xem xét sử dụng a StaticLayout, trong đó bạn cung cấp chiều rộng và lấy chiều cao. Để có câu trả lời rất tỉ mỉ về cách đo và vẽ văn bản vào canvas trong chế độ xem tùy chỉnh, hãy xem: https://stackoverflow.com/a/41779935/954643

Cũng cần lưu ý câu trả lời của @ arberg bên dưới về các pixel được vẽ so với chiều rộng nâng cao ("số pixel (trong float) mà con trỏ sẽ được nâng cao sau khi vẽ chuỗi đã cho"), trong trường hợp bạn cần giải quyết vấn đề đó.


2

Tôi muốn chia sẻ một cách tốt hơn (linh hoạt hơn sau đó là câu trả lời được chấp nhận hiện tại) để có được chiều rộng chính xác của văn bản được vẽ ( String) bằng cách sử dụng lớp tĩnh StaticLayout:

StaticLayout.getDesiredWidth(text, textPaint))

phương pháp này chính xác hơn textView.getTextBounds(), vì bạn có thể tính toán chiều rộng của một dòng trong nhiều dòng TextViewhoặc bạn có thể không sử dụng TextViewđể bắt đầu (ví dụ: trong Viewtriển khai tùy chỉnh ).

Cách này tương tự như textPaint.measureText(text), tuy nhiên nó có vẻ chính xác hơn trong một số trường hợp hiếm hoi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.