아래 코드에서 4가지 방법으로 화면 사이즈를 구하고 있다.
WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
Window window = mActivity.getWindow();
Rect windowRect = new Rect();
Rect screenRect = new Rect();
//Excludes status bar & soft key
window.getDecorView().getWindowVisibleDisplayFrame(windowRect);
//Whole screen
window.getDecorView().getGlobalVisibleRect(screenRect);
int topGap = windowRect.top - screenRect.top;
// Sometimes, status bar is at bottom...
int bottomGap = windowRect.bottom - screenRect.bottom;
int statusBarHeight = (bottomGap > topGap)? bottomGap:topGap;
Point outSize = new Point();
//Content screen
wm.getDefaultDisplay().getSize(outSize);
Log.i(TAG, "outSize " + outSize.toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Point realSize = new Point();
wm.getDefaultDisplay().getRealSize(realSize);//Whole screen
Log.i(TAG, "realSize " + realSize.toString());
}
실제 로그를 찍어보면, 대부분 값이 맞는데 폰마다 outSize 값이 다르게 나오는 경우가 있다. 소프트 키를 쓰든 하드웨어 키를 쓰든 outSize에서 알림바 높이가 빠져서 나오는 게 상식적으로 맞을 것 같지만 그렇지 않다. 아래는 갤노트4와 넥서스5를 비교한 것이다.
이와 관련해서 좀 당황스러운 것이 있다. PopupWindow를 화면 하단에 띄우려고 showAtLocation(View parent, Gravity gravity, int x, int y)을 실행했다. 이때 값이 (gravity=top, x=0, y=0). 상식적으로 outSize.bottom에서 커스텀 뷰의 높이만큼 빼면 커스텀 부가 놓일 위치가 나올텐데, 넥서스5에서는 꼭 알림바 높이만큼 차이가 난다. 난감하다.. 그래서 화면의 하단에 뷰를 놓고자 한다면 windowRect.bottom과 screenRect.bottom 이 다른지 비교해보자.
mViewY = windowRect.bottom - mContainer.getMeasuredHeight();
if(windowRect.bottom != screenRect.bottom) {
mViewY -= statusBarHeight;
}
Update : G2 롤리팝 버전(소프트키)에서는 넥서스5와 동일한 수치가 나오지만, 위 코드를 적용할 수 없다. 소프트 키를 갖고 있는 폰이지만 0,0 값의 기준이 팝업뷰의 parent 영역안에서 설정되는 듯...