TextView.setTextSize anormal davranıyor - Metin görünümünün metin boyutu farklı ekranlar için dinamik olarak nasıl ayarlanır


120

Arama TextView.setTextSize()anormal çalışıyor. Sağ çağrısının ardından setTextSizebir alırsanız getTextSizedaha önce ayarlayın şey bu onun dönen çok daha yüksek bir değere.

İşte yaptığımız şey:

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

Bunu daha önce gören oldu mu?


2
Metin boyutunu iki farklı nesne üzerinde mi ayarlıyorsunuz?
Cheryl Simon

Yanıtlar:


360

Buradaki fark, setTextSize(int size)yöntemde birim türünün varsayılan olarak "sp" veya "ölçeklenmiş pikseller" olmasıdır. Bu değer, her ekran yoğunluğu (ldpi, mdpi, hdpi) için farklı bir piksel boyutu olacaktır.

getTextSize()diğer yandan metnin gerçek piksel boyutlarını döndürür.

setTextSize(int unit, float size)Bir birim türü belirtmek için kullanabilirsiniz . Bunun sabit değerleri TypedValue sınıfında bulunabilir, ancak bazıları şunlardır:

TypedValue.COMPLEX_UNIT_PX   //Pixels

TypedValue.COMPLEX_UNIT_SP   //Scaled Pixels

TypedValue.COMPLEX_UNIT_DIP  //Device Independent Pixels

Bunu yeni buldum ve buraya göndermek üzereydim. Çok teşekkürler!
singhspk

1
Aslında TypedValue (tekil) ile olması gerektiğini düşünüyorum. İçe aktarma işlemi android.util.TypedValue;
Hein du Plessis

5
Ayrıca şunu da belirtmek gerekir ki, bunu sadece API seviyesi 7'de yapmaya başladı. Saçma bir API'de başka bir "yakaladım".
mxcl

3
Argüman sırasına dikkat etmek önemlidir - Yanlışlıkla setTextSize (size, TypedValue.COMPLEX_UNIT_SP) vardı çünkü yanlışlıkla varsaydığım sıra buydu!
Mark

1
İlginç bir şekilde, Galaxy Nexus'umdaki ICS'de setTextSize (14, TypedValue.COMPLEX_UNIT_SP) kullanmanın bir etkisi olmadı (bu nedenle varsayılan boyut kullanıldı), ancak Jelly Bean'e yükselttiğimde metnin hiçbiri görüntülenmedi (0 boyut gibi). Hatamı fark ettiğimde bir Jelly Bean hatasını bildirmek üzereydim!
Mark

20

Bu sorun, getTextSize()yöntemin boyutu piksel cinsinden döndürmesi ekran yoğunluğuna bağlı olduğu için ortaya çıkar! Gerçek Metin Boyutunu almak için şunu kullanın:

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

umarım çözer :)


2
Birlikte ekran ölçümlerini kullanarak benim sorun çözüldü setTextSize(int unit, float size).
Edward Chiang

8

Yazı tipi boyutunu değiştirmeyi ayarlamak , hata göstermeye neden olan bir şey varsa , şu şekilde yapabilirsiniz :

setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15.f);

3
TextSize'ı kim ayarlıyor DIP?
IgorGanapolsky

4

GetTextSize () ile programlı bir şekilde setText () problemini ayarlamaya çalıştığımızda, sp / dp / dip yerine px cinsinden değer döndürür ve 1sp / dp = 1.5px (ekran boyutu = 240) biliyoruz.

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

benim için mükemmel çalışıyor veya displaymatrix'i px: sp / dp oranına kullanabiliriz ve sonra bu değeri 1.5f ile değiştirebiliriz

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

3

Uzun zaman sonra bunu vurdu ve sonunda böyle çözdüm

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

res / values ​​/ Dimensions.xml gibi dimen klasörü oluşturun

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

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

 </resources>

2

Kısacası, metin boyutunuzu küçültmek istiyorsanız

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

GetTextSize () UNIT_PX döndürdüğünden, UNIT_PX kullanmalıyız


1

Kotlin Çözümü

Bir kaynak kullanarak ayarlamak için şunu kullanın:

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

Aynı şeyi bir kaynak değeriyle yapmak için, metin boyutunuzu çok daha kolay ayarlamak için bu uzantı özelliğini ekleyin

textView.textSizeRes = R.dimen.my_text_size

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

0

Bu cevaba biraz ekstra tat eklemek de biraz kafa karışıklığına neden oldu. Sen olmalıdır herhangi içine bu testi düşmesi mümkün @RunWith(AndroidJUnit4.class)sen (siz de dimens.xml için DIMENS eklemeniz gerekir) projenizde sahip testi.

Not: Tüm bu testler başarılı

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

Bulduğum en büyük paket TextView.setTextSize(float) , yazı tipi ölçeklendirmesinin uygulanmasıdır , bu nedenle DP yerine SP olarak etiketlenmiş bir boyut geçirirseniz, yazı tipi ölçeklendirmesini iki kez alır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.