獲取屏幕寬高尺寸的三種代碼形式
在Android上,目前我知道的獲取屏幕尺寸的方法有三種不同的代碼形式
方法1.在Activity中最常見的調用方式
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
由於在API Level 13以后上述的getWidth和getHeight包括getOrientation都變成了@Deprecated,所以屏幕寬高用getSize替換,也就有了方法2
Point outSize = new Point();
display.getSize(outSize);
screenWidth = outSize.x;
screenHeight = outSize.y;
顯然要做API Level的區分感覺會不太舒服,那么就有了第三種通用形式
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth =dm.widthPixels;
screenHeight =dm.heightPixels;
其實上述三種代碼形式,調用的都是WindowManager的default Display object里面的寬高尺寸,有些地方說上述這三種形式在屏幕未顯示時是拿不到具體值的,會拿到全是0的情況,我在Activity的onCreate函數中進行對其調用發現是能取到具體數值的,而且即使不在Activity中,通過Application的onCreate函數中的如下代碼:
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
也能順利拿到具體的屏幕寬高值。
獲取狀態欄的尺寸
由於decorView是window中的最頂層view,可以從window中獲取到decorView,然后decorView有個getWindowVisibleDisplayFrame方法可以獲取到程序顯示的區域,包括標題欄,但不包括狀態欄。
於是就有了算出狀態欄高度的第一種代碼形式
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
上述代碼有時候獲取到的高度是0,網上說法是在4.0.3版本以后的都會返回0,我沒有親測,但是在我的真機上確實拿到是0,網上流出一種在源碼程序中獲取狀態欄高度的代碼:
statusBarHeight = getResources().getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
那么在非源碼中應該怎么獲取呢?網上流行的一種解決方案,就是對上述需要源碼的實現方式通過反射來實現狀態欄高度的獲取,具體代碼如下:
import java.lang.reflect.Field;
//獲取手機狀態欄高度
public static int getStatusBarHeight(Context context){
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0, statusBarHeight = 38;//通常這個值會是38
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
return statusBarHeight;
}
經過測試發現這個函數在狀態欄隱藏的時候獲得的值和狀態欄顯示時的值是一樣的,不會變化,而且在做橫豎屏測試時,也是一樣不會改變,即狀態欄的高度在手機上應該是固定的。
上面方法是參考了網上有個獲取狀態欄高度的帖子而來的
http://www.cnblogs.com/renkangke/archive/2013/05/27/3101375.html
獲取標題欄高度
上面講了獲取狀態欄,順帶就引出如何獲取標題欄高度的問題,目前我所知道的獲取標題欄高度的方法是不能在onCreate函數中直接使用,必須在UI顯示出來后調用,具體大概是layout之后進行調用吧,具體代碼如下:
int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
//statusBarHeight是上面所求的狀態欄的高度
int titleBarHeight = contentTop – statusBarHeight;
上述方法的原理就是getWindow().findViewById(Window.ID_ANDROID_CONTENT)這個方法獲取到的view是程序不包括標題欄的部分。由於不能直接在onCreate函數中調用,所以有些調用方法是在onCreate中起一個線程,然后延時調用。
我也不知道有什么方法可以更加靠譜的獲取標題欄高度,如果有哪位技術牛人知道還望告知,另外這種方法與ContentView中的其它控件的尺寸獲取一樣,在onCreate中是無法直接獲取的,直接獲取都會是0。
另外在代碼中我們使用的是具體的像素值,具體像素值是與設備相關的,我們一般不在代碼中直接使用具體使用像素值,而是在資源文件中定義好設備無關的dp數值,然后通過類似如下方法獲取具體的像素值
int padding = getResources().getDimensionPixelSize(R.dimen.broadcast_select_padding);
有時候也有一種具體數值的方法來獲取像素值,比如上述的R.dimen.broadcast_select_padding假如是16dp,則可以通過下述方法獲取像素值
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int padding = 16 * dm.scaledDensity
但是這種方法我並不建議使用,因為Android的設備品類太多,在有些手機上這種乘法獲得的值與getResources().getDimensionPixelSize獲得的值並不相等,而后者肯定比前者准確。