TextView.setTextSize असामान्य रूप से व्यवहार करता है - अलग-अलग स्क्रीन के लिए टेक्स्टव्यू के टेक्स्ट आकार को गतिशील रूप से कैसे सेट करें


119

कॉल TextView.setTextSize()करना असामान्य रूप से काम कर रहा है। कॉल करने के ठीक बाद setTextSizeअगर हमें getTextSizeइसका रिटर्न बहुत ज्यादा मिलता है, तो हम इसे पहले से सेट कर देते हैं।

यहाँ हम क्या कर रहे हैं:

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

क्या किसी ने इसे पहले कभी देखा है?


2
आप दो अलग-अलग ऑब्जेक्ट पर टेक्स्ट का आकार प्राप्त कर रहे हैं और सेट कर रहे हैं?
चेरिल साइमन

जवाबों:


359

यहां अंतर यह है कि setTextSize(int size)विधि में, डिफ़ॉल्ट रूप से इकाई प्रकार "एसपी" या "स्केल्ड पिक्सल" है। यह मान प्रत्येक स्क्रीन घनत्व (ldpi, mdpi, hdpi) के लिए एक अलग पिक्सेल आयाम होगा।

getTextSize()दूसरी ओर, पाठ के वास्तविक पिक्सेल आयाम देता है।

आप setTextSize(int unit, float size)एक इकाई प्रकार निर्दिष्ट करने के लिए उपयोग कर सकते हैं । इसके लिए निरंतर मान TypedValue वर्ग में पाए जा सकते हैं, लेकिन उनमें से कुछ हैं:

TypedValue.COMPLEX_UNIT_PX   //Pixels

TypedValue.COMPLEX_UNIT_SP   //Scaled Pixels

TypedValue.COMPLEX_UNIT_DIP  //Device Independent Pixels

मुझे बस यही मिला और मैं इसे यहाँ पोस्ट करने वाला था। आपका बहुत बहुत धन्यवाद!
सिंहपार्क

1
मुझे लगता है कि यह वास्तव में TypedValue (एकवचन) द्वारा होना चाहिए। आयात android.util.TypedValue है;
हेन ड्यू प्लेसिस

5
यह भी ध्यान देने के लिए, यह केवल एपीआई स्तर 7 पर ऐसा करना शुरू कर दिया। हास्यास्पद एपीआई में एक और "गोचा"।
एमएक्सक्ल

3
तर्क आदेश के लिए बाहर देखना महत्वपूर्ण है - मैंने गलती से setTextSize (आकार, TypedValue.COMPLEX_UNIT_SP) किया था, क्योंकि यह वह क्रम था जो मैंने गलती से मान लिया था!
मार्क

1
दिलचस्प है, मेरे गैलेक्सी नेक्सस पर ICS पर, setTextSize (14, TypedValue.COMPLEX_UNIT_SP) का उपयोग करके कोई प्रभाव नहीं डाला (इसलिए डिफ़ॉल्ट आकार का उपयोग किया), लेकिन जब मैंने जेली बीन में अपग्रेड किया, तो कोई भी पाठ प्रदर्शित नहीं हुआ (जैसे 0 आकार)। मुझे अपनी गलती का एहसास होने पर मैं जेली बीन बग की रिपोर्ट करने वाला था!
मार्क

20

यह समस्या ख़ुशी की वजह है क्योंकि getTextSize()पिक्सेल में विधि का आकार स्क्रीन घनत्व पर निर्भर करता है! वास्तविक TextSize का उपयोग करने के लिए:

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

मुझे आशा है कि यह इसे हल :)


2
मैं मेरी समस्या के साथ प्रदर्शन मीट्रिक का उपयोग करके द्वारा हल setTextSize(int unit, float size)
एडवर्ड चियांग


4

जब हम getTextSize () के साथ प्रोग्रामेटिक रूप से सेटटैक् ट () की कोशिश करते हैं, तो sp / dp / dip के बजाय px में वैल्यू देता है और हम 1sp / dp = 1.5px (स्क्रीन साइज = 240) जानते हैं।

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

मेरे लिए पूरी तरह से काम कर रहा है या हम पीएक्स: एसपी / डीपी अनुपात के लिए डिस्प्लेमेट्रिक्स का उपयोग कर सकते हैं और फिर उस मूल्य को 1.5 एफ के साथ बदल सकते हैं

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

3

लंबे समय के बाद यह मारा और अंत में इस तरह से हल किया

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

इस रेस / मान / डाइमेंशन्स.xml जैसे डिमेन फोल्डर बनाएं

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

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

 </resources>

2

संक्षेप में, यदि आप अपने ग्रंथ को ज़ूम आउट करना चाहते हैं

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

क्योंकि getTextSize () UNIT_PX लौटाते हैं, तो हमें UNIT_PX का उपयोग करना चाहिए


1

कोटलिन समाधान

संसाधन का उपयोग करने के लिए, बस इसका उपयोग करें:

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

संसाधन मान के साथ ऐसा करने के लिए, इस एक्सटेंशन गुण को बहुत आसानी से अपने पाठ आकार को सेट करें

textView.textSizeRes = R.dimen.my_text_size

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

0

इस उत्तर के लिए कुछ अतिरिक्त स्वाद जोड़ना, क्योंकि यह थोड़ा भ्रम में चला गया। आपको अपनी परियोजना में होने वाले किसी भी परीक्षण में इस परीक्षा को छोड़ने में सक्षम होना चाहिए@RunWith(AndroidJUnit4.class) (आपको अपने डिमेंस को अपने डिमेंस.एमपीएम में जोड़ना होगा)।

नोट: ये सभी परीक्षण पास हैं

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

मेरे द्वारा पाया गया बड़ा टेकअवे TextView.setTextSize(float) फॉन्ट स्केलिंग को लागू करता है , इसलिए यदि आप डीपी के बजाय एसपी के रूप में पहले से ही लेबल किए गए डिमॉन थॉट में पास होते हैं, तो यह फ़ॉन्ट स्केलिंग को दो बार प्राप्त करेगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.