Android下setTextSize的正確使用姿勢(shì)

問幾個(gè)問題先

在app/src/main/res/values/dimens.xml中定義尺寸如下:

<dimen name="font1">18sp</dimen>

在代碼中引用此尺寸如下:

mText.setTextSize(18);  // 方法1
mText.setTextSize(getResources().getDimension(R.dimen.font1));  // 方法2
mText.setTextSize(TypedValue.COMPLEX_UNIT_PX,getResources().getDimension(R.dimen.font1));  // 方法3
mText.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);  // 方法4

問題1: 方法1和方法2設(shè)置的文字尺寸大小相同么?
問題2:方法3和方法4設(shè)置的文字尺寸大小相同么甘穿?
問題3:方法1和方法4設(shè)置的文字尺寸大小相同么机久?

如果你能很清楚的給出上面問題的答案仓洼,那就沒必要再向下看了矢腻;
如果你對(duì)以上問題感到模棱兩可的話煌张,請(qǐng)繼續(xù)往下看:

要想解開以上疑惑早歇,其實(shí)主要從以下兩個(gè)方法的源碼入手

setTextSize(...)

進(jìn)入TextView類焰檩,找到setTextSize(...)方法憔涉,發(fā)現(xiàn)它調(diào)用了另一個(gè)重載方法,注意這里調(diào)用重載方法時(shí)傳入的第一個(gè)參數(shù)是一個(gè)默認(rèn)值 TypedValue.COMPLEX_UNIT_SP析苫,因此方法1和方法4設(shè)置的文字尺寸大小相同.

public void setTextSize(float size) {
    setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}

public void setTextSize(int unit, float size) {   
    Context c = getContext();    
    Resources r;   
    if (c == null)        
        r = Resources.getSystem();    
    else        
        r = c.getResources();

    setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics()));
}
重載方法中有兩個(gè)方法需要重點(diǎn)看
setRawTextSize(...)方法

通過它的幾個(gè)方法會(huì)發(fā)現(xiàn)它的作用就是真正設(shè)置文字大小并刷新顯示:

private void setRawTextSize(float size) {    
    if (size != mTextPaint.getTextSize()) {            
        mTextPaint.setTextSize(size);        
        if (mLayout != null) {            
            nullLayouts();            
            requestLayout();            
            invalidate();        
        }    
    }
}
TypedValue類中的applyDimension(...)方法

根據(jù)傳入的unit單位來處理文字大小兜叨,返回的尺寸為px (通過第一個(gè)case條件得知).

public static float applyDimension(int unit, float value, DisplayMetrics metrics){
    switch (unit) {    
        case COMPLEX_UNIT_PX:        
            return value;    
        case COMPLEX_UNIT_DIP:        
            return value * metrics.density;    
        case COMPLEX_UNIT_SP:        
            return value * metrics.scaledDensity;    
        case COMPLEX_UNIT_PT:        
            return value * metrics.xdpi * (1.0f/72);    
        case COMPLEX_UNIT_IN:        
            return value * metrics.xdpi;    
        case COMPLEX_UNIT_MM:        
            return value * metrics.xdpi * (1.0f/25.4f);    
    }    
    return 0;
}

如果傳入的unit為COMPLEX_UNIT_PX穿扳,則會(huì)將value直接返回
如果傳入的unit為COMPLEX_UNIT_SP,則會(huì)將value處理成px返回

getDimension(...)

進(jìn)入Resources類国旷,找到getDimension(...)方法

public float getDimension(@DimenRes int id) throws NotFoundException {
    synchronized (mAccessLock) {        
        TypedValue value = mTmpValue;        
        if (value == null) {            
            mTmpValue = value = new TypedValue();        
        }        
        getValue(id, value, true);        
        if (value.type == TypedValue.TYPE_DIMENSION) {            
            return TypedValue.complexToDimension(value.data, mMetrics);        
        }        
        throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id) + " type #0x" + Integer.toHexString(value.type) + " is not valid");    
    }
}

這里方法不多矛物,點(diǎn)getValue(...)方法進(jìn)去看會(huì)發(fā)現(xiàn)它內(nèi)部又調(diào)用了native方法,這里我無法進(jìn)一步追溯它的實(shí)現(xiàn)跪但,不過沒關(guān)系履羞,因?yàn)槲野l(fā)現(xiàn)有個(gè)方法很眼熟那就是:TypedValue.complexToDimension(...) ,進(jìn)入此方法會(huì)驚奇的發(fā)現(xiàn)它也調(diào)用了上面講到的applyDimension(...)方法.

public static float complexToDimension(int data, DisplayMetrics metrics){    
    return applyDimension(        
        (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK, complexToFloat(data), metrics);
}

由此可以大膽的猜測(cè) getDimension(...)方法最終也會(huì)將數(shù)據(jù)處理成px返回屡久,因此方法3和方法4設(shè)置的文字尺寸大小相同忆首,只是寫法不同而已.

好了,回到開篇提到的四個(gè)問題被环,可以得出以下結(jié)論:

方法1:文字尺寸以sp為單位糙及,大小為18
方法2:文字尺寸以sp為單位,大小為(18sp轉(zhuǎn)換為px的值)
方法3:文字尺寸以px為單位蛤售,大小為(18sp轉(zhuǎn)換為px的值)
方法4:文字尺寸以sp為單位丁鹉,大小為18

方法1=方法3=方法4!=方法2

至此妒潭,文章結(jié)束悴能,希望此文能幫助到你,如果對(duì)此文有不同見解雳灾,歡迎直接評(píng)論漠酿!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谎亩,隨后出現(xiàn)的幾起案子炒嘲,更是在濱河造成了極大的恐慌,老刑警劉巖匈庭,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夫凸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡阱持,警方通過查閱死者的電腦和手機(jī)夭拌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衷咽,“玉大人鸽扁,你說我怎么就攤上這事∠馄” “怎么了桶现?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鼎姊。 經(jīng)常有香客問我骡和,道長(zhǎng)相赁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任慰于,我火速辦了婚禮噪生,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘东囚。我一直安慰自己跺嗽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布页藻。 她就那樣靜靜地躺著桨嫁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪份帐。 梳的紋絲不亂的頭發(fā)上璃吧,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音废境,去河邊找鬼畜挨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛噩凹,可吹牛的內(nèi)容都是我干的巴元。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼驮宴,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼逮刨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起堵泽,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤修己,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后迎罗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睬愤,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年纹安,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尤辱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钻蔑,死狀恐怖啥刻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情咪笑,我是刑警寧澤可帽,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站窗怒,受9級(jí)特大地震影響映跟,放射性物質(zhì)發(fā)生泄漏蓄拣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一努隙、第九天 我趴在偏房一處隱蔽的房頂上張望球恤。 院中可真熱鬧,春花似錦荸镊、人聲如沸咽斧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)张惹。三九已至,卻和暖如春岭洲,著一層夾襖步出監(jiān)牢的瞬間宛逗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工盾剩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雷激,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓告私,卻偏偏與公主長(zhǎng)得像屎暇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子德挣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容