TextView.setTextSize hoạt động bất thường - Cách đặt kích thước văn bản của chế độ xem văn bản cho các màn hình khác nhau


119

Gọi TextView.setTextSize()đang làm việc bất thường. Ngay sau cuộc gọi đến setTextSizenếu chúng tôi nhận được getTextSizenó sẽ trả về giá trị cao hơn nhiều so với giá trị mà chúng tôi đã đặt trước đó.

Đây là những gì chúng tôi đang làm:

zoomControl.setOnZoomInClickListener(new OnClickListener() {
    public void onClick(View view) {
        float size = mViewShabad.getTextSize() + 1;
        textView.setTextSize(size);
    }
});

Có ai thấy điều này trước đây không?


2
Bạn đang nhận và đặt kích thước văn bản trên hai đối tượng khác nhau?
Cheryl Simon

Câu trả lời:


359

Sự khác biệt ở đây là trong setTextSize(int size)phương thức, loại đơn vị theo mặc định là "sp" hoặc "pixel được chia tỷ lệ". Giá trị này sẽ là kích thước pixel khác nhau cho mỗi mật độ màn hình (ldpi, mdpi, hdpi).

getTextSize()mặt khác, trả về kích thước pixel thực của văn bản.

Bạn có thể sử dụng setTextSize(int unit, float size)để chỉ định một loại đơn vị. Các giá trị không đổi cho điều này có thể được tìm thấy trong lớp TypedValue, nhưng một số trong số chúng là:

TypedValue.COMPLEX_UNIT_PX   //Pixels

TypedValue.COMPLEX_UNIT_SP   //Scaled Pixels

TypedValue.COMPLEX_UNIT_DIP  //Device Independent Pixels

Tôi chỉ tìm thấy điều đó và chuẩn bị đăng nó ở đây. Cảm ơn rất nhiều!
singhspk

1
Tôi nghĩ rằng nó thực sự nên bởi TypedValue (số ít). Nhập khẩu là android.util.TypedValue;
Hein du Plessis 22/03

5
Cũng cần lưu ý, nó chỉ bắt đầu thực hiện điều này ở cấp độ API 7. Một "gotcha" khác trong một API lố bịch.
mxcl

3
Điều quan trọng là phải coi chừng thứ tự đối số - Tôi đã vô tình có setTextSize (kích thước, TypedValue.COMPLEX_UNITinks) vì đó là thứ tự tôi đoán nhầm!
Đánh dấu

1
Thật thú vị, trên ICS trên Galaxy Nexus của tôi, sử dụng setTextSize (14, TypedValue.COMPLEX_UNITinks) không có tác dụng (nên sử dụng kích thước mặc định), nhưng khi tôi nâng cấp lên Jelly Bean, không có văn bản nào được hiển thị (như kích thước 0). Tôi vừa báo cáo lỗi Jelly Bean khi nhận ra lỗi của mình!
Đánh dấu

20

vấn đề này xảy ra vì getTextSize()phương thức trả về kích thước tính bằng pixel phụ thuộc vào mật độ màn hình! để có được TextSize thực tế, hãy sử dụng:

DisplayMetrics metrics;
metrics = getApplicationContext().getResources().getDisplayMetrics();
float Textsize =myTextView.getTextSize()/metrics.density;
myTextView.setTextSize(Textsize+1);

tôi hy vọng nó giải quyết nó :)


2
Tôi giải quyết vấn đề của tôi bằng cách sử dụng các số liệu hiển thị với setTextSize(int unit, float size).
Edward Chiang

8

nếu Cài đặt thay đổi kích thước phông chữ gây ra lỗi hiển thị bạn có thể làm như là

setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15.f);

3
Ai đặt textSize trong DIP?
IgorGanapolsky

4

Khi chúng tôi cố gắng thiết lập vấn đề theo chương trình với getTextSize (), trả về giá trị bằng px thay vì sp / dp / dip và chúng tôi biết 1sp / dp = 1.5px (kích thước màn hình = 240).

 titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*1.5f)); 

đang hoạt động hoàn hảo đối với tôi hoặc chúng tôi có thể sử dụng tỷ lệ displaymatrix để px: sp / dp sau đó thay thế giá trị đó bằng 1,5f

means-> titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*your_sp_and_px_ratio_in_int f));

3

Sau một thời gian dài đánh bại điều này và cuối cùng đã giải quyết như thế này

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
          getResources().getDimension(R.dimen.textsize));

tạo thư mục làm mờ như thế này res / value / kích thước

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <dimen name="textsize">8sp</dimen>

 </resources>

2

Nói tóm lại, nếu bạn muốn thu nhỏ kích thước văn bản của mình

float size = mViewShabad.getTextSize()*1.1f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);

Vì getTextSize () trả về UNIT_PX, nên chúng ta nên sử dụng UNIT_PX


1

Giải pháp Kotlin

Để thiết lập sử dụng tài nguyên, chỉ cần sử dụng tài nguyên này:

textView.setTextSize(COMPLEX_UNIT_PX, textView.resources.getDimension(R.dimen.my_text_size))

Để làm tương tự với giá trị tài nguyên, hãy thêm thuộc tính tiện ích mở rộng này để dễ dàng đặt kích thước văn bản của bạn hơn

textView.textSizeRes = R.dimen.my_text_size

var TextView.textSizeRes
    get() = textSize.toInt()
    set(@DimenRes textSizeRes) {
        setTextSize(COMPLEX_UNIT_PX, resources.getDimension(textSizeRes))
    }

0

Thêm một số hương vị bổ sung cho câu trả lời này, cũng như có một chút nhầm lẫn. Bạn sẽ có thể thả thử nghiệm này vào bất kỳ @RunWith(AndroidJUnit4.class)thử nghiệm nào bạn có trong dự án của mình (bạn cũng sẽ cần thêm các độ mờ vào dimens.xml của mình).

Lưu ý: Tất cả các bài kiểm tra này đều vượt qua

@Test public void testScaledFontSizes() {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    final Context context = InstrumentationRegistry.getTargetContext();

    Configuration configuration = context.getResources().getConfiguration();
    configuration.fontScale = 2.0f;
    configuration.densityDpi = 160; // mdpi, 1:1
    context.getResources().updateConfiguration(configuration, null);

    float scaledTextSize = context.getResources().getDimensionPixelSize(R.dimen.sp_15);
    assertEquals(30.0f, scaledTextSize);

    // Create a new TextView with the explicitly set configuration
    TextView textView = new TextView(context);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, scaledTextSize);

    // 30, because font size is scaled
    assertEquals(30.0f, textView.getTextSize());

    // This is what we *don't* want, it's scaled *twice*!
    textView.setTextSize(scaledTextSize);
    assertEquals(60.0f, textView.getTextSize());

    // DP instead of SP tests
    float fifteenDp = context.getResources().getDimensionPixelSize(R.dimen.dp_15);
    assertEquals(15.0f, fifteenDp);

    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, fifteenDp);
    // Still 15, because it's DP, not SP
    assertEquals(15.0f, fifteenDp);

    textView.setTextSize(fifteenDp);
    // 30, because setTextSize DOES font scaling
    assertEquals(30.0f, textView.getTextSize());
  }
}

Điểm nổi bật mà tôi tìm thấy là TextView.setTextSize(float) áp dụng tỷ lệ phông chữ , vì vậy nếu bạn chuyển qua một chữ mờ được dán nhãn là SP thay vì DP, thì nó sẽ nhận được tỷ lệ phông chữ hai lần .

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.