當我們要在Layout 中定義控制項的長寬等維度時,Android的推薦是:
1)所有長寬的單位都定義成dip,除了字型的大小
2)字型的大小用sp來表示
這篇文章我們討論一下,為什麼不用像素 px, 而要用dip 表示呢? dip 跟 px 之前的關係是什麼呢?
實踐出真知,代碼來展示。
我們先來定義兩個按鈕,其中一個的寬度是160 dip, 另外一個的寬度是160 px,(注意單位不同)然後來看看在不同的模擬器上有什麼不一樣。
同時也定義了幾個TextView, 來展示螢幕的寬度,螢幕密度比例 和 螢幕的密度。
public class DipActivity extends Activity{public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);DisplayMetrics displayMetrics = getResources().getDisplayMetrics();float density = displayMetrics.density;int densityDpi = displayMetrics.densityDpi;int screenWidth = displayMetrics.widthPixels;setContentView(R.layout.dip_layout);TextView textViewSw = (TextView)findViewById(R.id.textViewSw);textViewSw.setText("screen Width (px):" + screenWidth);TextView dpView = (TextView)findViewById(R.id.textViewDp);dpView.setText("Density :" + density);TextView pxView = (TextView)findViewById(R.id.textViewPx);pxView.setText("Density Dpi : " + String.valueOf(densityDpi));}}
然後我們運行代碼,看看效果怎麼樣?如下,上面的是在480*800的模擬器上,下面是在320*480的模擬器上。
我們先來看螢幕為480*800的機器,
Button的寬度為160dip的很明顯要比160px的要長,事實上,160dip的按鈕佔據了一半的寬度(240px),而160px的Button,就是160px.<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+zqrKssO0u+HV4tH5xNijv8bkyrW+zcrHuPrNvMnP1bnKvrXERGVuc2l0edPQudjBy6OsztKw0cv8s8bOqsPctsixyMD9o6zL/LXEJiMyMDU0MDvKx7Wxx7DGwcS7tcRkcGkgo6hEb3QgUGVyIEluY2gssrvKx2RpcKOpuPogMTYwILXE0ru49rHIwP2hozwvcD4KPHA+1NrGwcS7w9y2yCBEZW5zaXR5IGRwaSDOqjI0MLXEyta7+snPo6zD3LbIscjA/URlbnNpdHkgPSAyNDAgLyAxNjAgPSAxLjUuIDwvcD4KPHA+tvhkaXAguPogcHggtcTWrrzktcSxyMD9INTyzqogcHggPSBkaXAgKiAxLjUsILy0tbHO0sPH1NqyvL7W1tDJ6NbDsLTFpbXEv+3OqjE2MGRpcMqxo6y1scv8vq25/c+1zbO1xLu7y+OjrNW5z9bU2sbBxLvJz7XE0tG+rcrHz/HL2KOstvjG5CYjMjA1NDA7vs3KxzE2MCAqIDEuNSA9IDI0MHB4LjwvcD4KPHA+1NpBbmRyb2lkyta7+tbQo6zSu7Dj09DPwsPmNLj2vLax8LXExsHEu8PctsijrDwvcD4KPHA+MaOpMTIwIC0gTG93ILbU06a1xGRlbnNpdHkgPSAxMjAgLyAxNjAgPSAwLjc1PC9wPgo8cD4yo6kxNjAgLSBNZWRpdW0gttTTprXEZGVuc2l0eSA9IDE2MCAvIDE2MCA9IDEuMCA8L3A+CjxwPjOjqTI0MCAtIEhpZ2ggttTTprXEZGVuc2l0eSA9IDI0MCAvIDE2MCA9IDEuNTwvcD4KPHA+NKOpMzIwIC0gRXh0cmEgSGlnaCC21NOmtcRkZW5zaXR5ID0gMzIwIC8gMTYwID0yLjA8L3A+CjxwPtXiuPYmIzIwNTQwO7/J0tTNqLn9RGlzcGxheU1ldHJpY3PAtMTDtb2jrMjnz8KjujwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">DisplayMetrics displayMetrics = getResources().getDisplayMetrics();float density = displayMetrics.density;int densityDpi = displayMetrics.densityDpi;int screenWidth = displayMetrics.widthPixels;當我們在布局中以dip為單位的時候,中間其實會經過系統的換算,根據不同的螢幕密度,將其轉換成對應螢幕的像素,從而達到適應不同螢幕解析度的問題。
在320*480的機器上,可以看到Density Dpi = 160, 那麼其Density = 160/160 = 1.0, 那麼160dip 轉換成像素就是 160 * 1.0 = 160px.
所以160dip的按鈕跟160px的按鈕在螢幕上展現是一樣寬的。
綜合兩個圖來看,當我們定義160dip的時候,無論是在上邊的機器還是下邊的機器,按鈕都是佔據螢幕的一半寬度,而如果定義成160px的話,則達不到這樣的效果。
我想這也就是為什麼Android會推薦用dip而不推薦px了,因為不同解析度的手機螢幕實在是太多了,用像素的話,定死了,真不好看。
而用dip,則系統會去讀取螢幕的密度,再根據密度比例來計算真正要展現在螢幕上的像素,效果會好很多。