android自定义属性dimen,android代码里的dimen
在自定義控件中使用自定義屬性時,經(jīng)常需要使用java代碼獲取在xml中定義的尺寸,相關(guān)有以下三個函數(shù)
getDimension()
getDimensionPixelOffset()
getDimensionPixelSize()
(在類TypedArray和類Resources中都有這三個函數(shù),功能類似,TypedArray中的函數(shù)是獲取自定義屬性的,Resources中的函數(shù)是獲取android預(yù)置屬性的)
通常初學(xué)者(尤其是洋文不大好的朋友們)看到這三個函數(shù)的名稱時會有點(diǎn)不知所云。反正在我仔細(xì)研究前是這樣,getDimensionPixelSize()函數(shù)看名稱是獲取像素,那getDimensionPixelOffset()這玩意兒的offset是啥(通常API里不都是 begin, offset, len么)???getDimension()這個函數(shù)又是干啥的,和getDimensionPixelSize()有什么區(qū)別嗎,是獲取原始的dp值嗎(答案是否定的)?
高手請無視本帖,不太明白的初學(xué)者可以往下仔細(xì)看看哦~
帶著這些疑惑,看看API reference里的解釋:
getDimension()是基于當(dāng)前DisplayMetrics進(jìn)行轉(zhuǎn)換,獲取指定資源id對應(yīng)的尺寸。文檔里并沒說這里返回的就是像素,要注意這個函數(shù)的返回值是float,像素肯定是int。
getDimensionPixelSize()與getDimension()功能類似,不同的是將結(jié)果轉(zhuǎn)換為int,并且小數(shù)部分四舍五入。
getDimensionPixelOffset()與getDimension()功能類似,不同的是將結(jié)果轉(zhuǎn)換為int,并且偏移轉(zhuǎn)換(offset conversion,函數(shù)命名中的offset是這個意思)是直接截斷小數(shù)位,即取整(其實(shí)就是把float強(qiáng)制轉(zhuǎn)化為int,注意不是四舍五入哦)。
由此可見,這三個函數(shù)返回的都是絕對尺寸,而不是相對尺寸(dp\sp等)。如果getDimension()返回結(jié)果是20.5f,那么getDimensionPixelSize()返回結(jié)果就是21,getDimensionPixelOffset()返回結(jié)果就是20。
到這里本帖就可以結(jié)束了,但如果想知道的多一點(diǎn),還可以看看android的源代碼,來印證上述解釋。
深入源碼,我們可以發(fā)現(xiàn)其實(shí)這三個函數(shù)實(shí)現(xiàn)都很像,以Resources類的getDimension()為例
[mw_shl_code=java,true]? ? public float getDimension(int id) throws NotFoundException { ? ?? ???synchronized (mTmpValue) { ? ?? ?? ?? ?TypedValue value = mTmpValue; ? ?? ?? ?? ?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"); ? ?? ???} ? ? }[/mw_shl_code]
類TypedValue是動態(tài)類型數(shù)據(jù)的容器,主要用于盛放resource的值。上述代碼第4行就是根據(jù)resId獲取TypedValue的值,getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()函數(shù)體唯一的不同就是第4行:
getDimension()調(diào)用的是TypedValue的complexToDimension方法
getDimensionPixelSize調(diào)用的是TypedValue的complexToDimensionPixelSize方法
getDimensionPixelOffset調(diào)用的是TypedValue的complexToDimensionPixelOffset方法
我們再深入類TypedValue,查看complexToDimension()、complexToDimensionPixelSize()和complexToDimensionPixelOffset()函數(shù)的區(qū)別,會發(fā)現(xiàn)這三個函數(shù)體內(nèi)容還是差不多,以complexToDimension()為例:
[mw_shl_code=java,true]? ? public static float complexToDimension(int data, DisplayMetrics metrics)
{
return applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}[/mw_shl_code]
complexToDimensionPixelOffset()與complexToDimension()不同的是將結(jié)果進(jìn)行了強(qiáng)制轉(zhuǎn)換,相當(dāng)于直接截斷小數(shù)部分; complexToDimensionPixelSize()是將結(jié)果進(jìn)行四舍五入,四舍五入的代碼就是把結(jié)果加上0.5f再進(jìn)行強(qiáng)制轉(zhuǎn)換(因為java的float強(qiáng)制轉(zhuǎn)換為int都是直接舍去小數(shù)的;如果大于等于0.5則加上0.5進(jìn)位,強(qiáng)制轉(zhuǎn)換后舍去小數(shù)相當(dāng)于五入;如果小于0.5則加上0.5后整數(shù)部分不變,強(qiáng)制轉(zhuǎn)換舍去小數(shù)后相當(dāng)于四舍,java基礎(chǔ),第一次接觸的新手普及下~)
ok了,簡單的源碼分析完成了。 通過源碼分析,進(jìn)一步驗證了getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()的區(qū)別,大家以后再用到這三個函數(shù)的時候就不用發(fā)蒙了。在java代碼里很多setWidth(),setHeight()的參數(shù)都是像素,即整形,大家根據(jù)實(shí)際情況,看看如果是四舍五入就調(diào)用getDimensionPixelSize(),如果是取整就調(diào)用getDimensionPixelOffset()。千萬不要setWidth((int)getDimension()) 這么寫哦!
后記: android并沒有在java代碼中直接獲取xml中定義的dp\sp的值的API,可能是因為google認(rèn)為沒有必要。但如果實(shí)在想得到xml中咱們自己寫的dp或sp的值(例如想在日志里輸出dp\sp什么的),請參見我的另一個帖子Java代碼獲取xml中定義的dp\sp值的方法
總結(jié)
以上是生活随笔為你收集整理的android自定义属性dimen,android代码里的dimen的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 字体渲染机制,Andro
- 下一篇: 如何把js变量传递给html页面,如何将