Android에서 상태 표시 줄의 높이는 얼마입니까? 항상 같은가요?
내 측정 결과 25dp 인 것처럼 보이지만 모든 플랫폼에서 높이가 같은지 확실하지 않습니다.
(상태 표시 줄이없는 활동에서 그렇지 않은 활동으로 페이드 전환을 올바르게 구현하려면 이것을 알고 싶습니다.)
Android에서 상태 표시 줄의 높이는 얼마입니까? 항상 같은가요?
내 측정 결과 25dp 인 것처럼 보이지만 모든 플랫폼에서 높이가 같은지 확실하지 않습니다.
(상태 표시 줄이없는 활동에서 그렇지 않은 활동으로 페이드 전환을 올바르게 구현하려면 이것을 알고 싶습니다.)
답변:
이 질문은 전에 답변되었습니다 ... 상태 표시 줄의 높이?
업데이트 ::
예, 상태 표시 줄의 높이는 화면 크기에 따라 다릅니다 (예 : 240 x 320 화면 크기의 장치의 경우 상태 표시 줄 높이는 20px, 320 x 480 화면 크기의 장치의 경우 상태 표시 줄 높이는 25px입니다) 상태 표시 줄 높이가 480 x 800 인 기기는 38 픽셀이어야합니다.
이 스크립트를 사용하여 상태 표시 줄 높이를 얻는 것이 좋습니다.
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop =
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;
Log.i("*** Elenasys :: ", "StatusBar Height= " + statusBarHeight + " , TitleBar Height = " + titleBarHeight);
onCreate()
활동 방법 에서 상태 표시 줄의 높이를 얻으려면 다음 방법을 사용하십시오.public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)
다중 창 모드 + 세로 회전 + 두 번째 창에있는 경우 상태 표시 줄 높이를 얻는 올바른 방법이 아닙니다. 큰 값을 얻습니다 (첫 번째 높이 포함).
상태 표시 줄의 높이를 얻는 데 사용한 모든 코드 샘플 중에서 실제로 onCreate
메서드 에서 작동하는 유일한 Activity
것은 다음과 같습니다.
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
분명히 상태 표시 줄의 실제 높이는 Android 리소스로 유지됩니다. 위의 코드는 ContextWrapper
클래스에 추가 할 수 있습니다 (예 :) Activity
.
http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/ 에서 발견
MDPI 장치에서 상태 표시 줄은 25px입니다. 이것을 기본으로 사용하고 밀도 (반올림)를 곱하여 모든 장치에서 상태 표시 줄 높이를 얻을 수 있습니다.
int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);
참조 : ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2
크기를 하드 코딩하거나 리플렉션을 사용하여 값을 얻는 것은 status_bar_height
나쁜 습관으로 간주됩니다. Chris Banes 는 Droidcon New York에서 이에 대해 이야기했습니다 . 상태 표시 줄 크기를 얻는 권장 방법은 OnApplyWindowInsetsListener 를 사용하는 것입니다 .
myView.setOnApplyWindowInsetsListener { view, insets -> {
val statusBarSize = insets.systemWindowInsetTop
return insets
}
이것은 API 20에 추가되었으며 ViewAppCompat 를 통해 백 포트됩니다 .
몇 가지 솔루션을 병합했습니다.
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
return resources.getDimensionPixelSize(resourceId);
else
return (int) Math.ceil((VERSION.SDK_INT >= VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
}
다른 대안 :
final View view = findViewById(android.R.id.content);
runJustBeforeBeingDrawn(view, new Runnable() {
@Override
public void run() {
int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
}
});
편집 : runJustBeforeBeingDrawn의 대안 : https://stackoverflow.com/a/28136027/878126
구글 디자인 가이드 라인 에 따르면 ; 상태 표시 줄의 높이는 24dp입니다.
상태 표시 줄 높이를 픽셀 단위로 얻으려면 아래 방법을 사용할 수 있습니다.
private static int statusBarHeight(android.content.res.Resources res) {
return (int) (24 * res.getDisplayMetrics().density);
}
다음을 사용하여 활동에서 호출 할 수 있습니다.
statusBarHeight(getResources());
onCreate에서 상태 표시 줄 높이를 가져야하는 것과 동일한 문제가 있습니다. 이것은 나를 위해 작동합니다.
private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;
private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;
private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;
onCreate 내부 :
DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
int statusBarHeight;
switch (displayMetrics.densityDpi) {
case DisplayMetrics.DENSITY_HIGH:
statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
break;
case DisplayMetrics.DENSITY_MEDIUM:
statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
break;
case DisplayMetrics.DENSITY_LOW:
statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
break;
default:
statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
}
보다:
http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
공식 높이는 Android 디자인 웹 페이지24dp
에서 Google이 공식적으로 명시한대로입니다 .
예, View로 시도하면 25px의 결과를 제공합니다. 전체 코드는 다음과 같습니다.
public class SpinActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout lySpin = new LinearLayout(this);
lySpin.setOrientation(LinearLayout.VERTICAL);
lySpin.post(new Runnable()
{
public void run()
{
Rect rect = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int contentViewTop =
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight = contentViewTop - statusBarHeight;
System.out.println("TitleBarHeight: " + titleBarHeight
+ ", StatusBarHeight: " + statusBarHeight);
}
}
}
}
이 시도:
Rect rect = new Rect();
Window win = this.getWindow();
win.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight = contentViewTop - statusBarHeight;
Log.d("ID-ANDROID-CONTENT", "titleBarHeight = " + titleBarHeight );
그것은 활동에 대한 onCreate 메소드에서 작동하지 않았지만 onClickListener에 넣고 25의 측정을주었습니다.
안드로이드 6.0에서 상태 표시 줄의 높이는 24dp입니다
<!-- Height of the status bar -->
<dimen name="status_bar_height">24dp</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
소스 코드에서 답변을 찾을 수 있습니다 : frameworks \ base \ core \ res \ res \ values \ dimens.xml
@android:dimen/status_bar_height
나를 위해 작동하지 않습니다
이 문제를 해결하기 위해 조합 접근법을 사용했습니다. 이것은 태블릿에서 display.getHeight ()가 호출 될 때 시스템 막대가 이미 픽셀을 빼기 때문에 필요합니다. 먼저 시스템 표시 줄이 있는지 확인한 다음 Ben Claytons가 전화로 접근합니다.
public int getStatusBarHeight() {
int statusBarHeight = 0;
if (!hasOnScreenSystemBar()) {
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
}
return statusBarHeight;
}
private boolean hasOnScreenSystemBar() {
Display display = getWindowManager().getDefaultDisplay();
int rawDisplayHeight = 0;
try {
Method getRawHeight = Display.class.getMethod("getRawHeight");
rawDisplayHeight = (Integer) getRawHeight.invoke(display);
} catch (Exception ex) {
}
int UIRequestedHeight = display.getHeight();
return rawDisplayHeight - UIRequestedHeight > 0;
}
@Niklas +1 덕분에 올바른 방법입니다.
public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {
Rect windowInsets;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
View rootview = findViewById(android.R.id.content);
android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
}
android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
{
windowInsets = new Rect();
windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
//StatusBarHeight = insets.getSystemWindowInsetTop();
//Refresh/Adjust view accordingly
return insets;
}
}
코드가 100 % 정확하지 않은 경우 실례합니다 .Xamarin C #에서 코드를 변환했지만 이것이 바로 그 것입니다. 노치 등과 함께 작동
전체 화면 솔루션 전환 :
이 솔루션은 해결 방법처럼 보이지만 실제로는 앱이 전체 화면 (상태 표시 줄 숨기기)인지 여부를 설명합니다.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();
이렇게하면 앱이 현재 전체 화면 인 barheight
경우 0이됩니다.
개인적으로 나는 상태 표시 줄을 설명하기 위해 절대 TouchEvent 좌표를 수정하기 위해 이것을 사용해야했습니다.
@Override
public boolean onTouch(View view,MotionEvent event) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int YCoord = (int)event.getRawY() - size.y + rootView.getHeight());
}
그리고 앱이 전체 화면인지 여부에 관계없이 절대 y 좌표를 얻습니다.
즐겨
Android 4.1 이상에서는 상태 표시 줄이 숨겨져 표시 될 때 내용의 크기가 조정되지 않도록 응용 프로그램의 내용을 상태 표시 줄 뒤에 표시하도록 설정할 수 있습니다. 이렇게하려면 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN을 사용하십시오. 앱이 안정적인 레이아웃을 유지하는 데 도움이되도록 SYSTEM_UI_FLAG_LAYOUT_STABLE을 사용해야 할 수도 있습니다.
이 접근 방식을 사용하면 앱 UI의 중요한 부분 (예 :지도 애플리케이션의 내장 컨트롤)이 시스템 표시 줄에 얽 히지 않도록해야합니다. 앱을 사용할 수 없게 될 수 있습니다. 대부분의 경우 android : fitsSystemWindows 속성을 XML 레이아웃 파일에 추가하여 true로 설정하여이를 처리 할 수 있습니다. 이것은 시스템 창을위한 공간을 남기기 위해 부모 ViewGroup의 패딩을 조정합니다. 대부분의 응용 프로그램에 충분합니다.
그러나 경우에 따라 앱의 원하는 레이아웃을 얻기 위해 기본 패딩을 수정해야 할 수도 있습니다. 윈도우의 "컨텐츠 삽입"으로 알려진 공간을 차지하는 시스템 막대를 기준으로 컨텐트가 배치되는 방식을 직접 조작하려면 fitSystemWindows (Rect insets)를 재정의하십시오. fitSystemWindows () 메소드는 창의 컨텐츠 삽입이 변경 될 때 뷰 계층 구조에 의해 호출되어, 이에 따라 창의 컨텐츠를 조정할 수 있습니다. 이 방법을 재정의하면 원하는대로 삽입물 (및 따라서 앱의 레이아웃)을 처리 할 수 있습니다.
양식 : https://developer.android.com/training/system-ui/status.html#behind
크기 VS 높이를 정확히 알고 있다면
처럼
예를 들어 320 x 480 화면 크기의 기기에서는 상태 표시 줄 높이가 25 픽셀이고 480 x 800 인 기기의 경우 상태 표시 줄 높이는 38 픽셀이어야합니다.
그런 다음 뷰 너비 / 화면 크기를 얻을 수 있습니다 .if else 문을 사용하여 상태 표시 줄의 높이를 얻을 수 있습니다
일부 사람들에게 최고 답변이 작동하지 않는 이유는 렌더링 준비가 될 때까지 뷰의 크기를 얻을 수 없기 때문입니다. OnGlobalLayoutListener
실제로 다음을 수행 할 수있는 경우 치수를 사용하려면
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= 16) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
// Nice one, Google
decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
rect.top; // This is the height of the status bar
}
}
}
이것이 가장 안정적인 방법입니다.
현재 다중 창 모드를 사용할 수 있으므로 앱의 상태 표시 줄이 맨 위에 표시되지 않을 수 있습니다.
다음 솔루션은 모든 사례를 자동으로 처리합니다.
android:fitsSystemWindows="true"
또는 프로그래밍 방식으로
findViewById(R.id.your_root_view).setFitsSystemWindows(true);
당신은 또한 루트보기를 얻을 수 있습니다
findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)
루트 뷰를 얻는 방법에 대한 자세한 내용은 https://stackoverflow.com/a/4488149/9640177을 참조 하십시오.
이 문제는 최근 Pixel 3XL의 노치 때문에 관련이되었습니다. 나는 안드로이드 개발자의 솔루션을 정말로 좋아 했지만, 내가 재생 해야하는 전체 화면 애니메이션이 특별히 필요했기 때문에 상태 표시 줄 높이를 자유롭게 얻을 수 있기를 원했습니다. 아래 함수는 신뢰할 수있는 쿼리를 가능하게했습니다.
private val DEFAULT_INSET = 96
fun getInsets(view: View?): Int {
var inset = DEFAULT_INSET
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Safe because only P supports notches
inset = view?.rootWindowInsets?.stableInsetTop ?: DEFAULT_INSET
}
return inset
}
fun blurView(rootView: View?, a: SpacesActivity?) {
val screenBitmap = getBitmapFromView(rootView!!)
val heightDifference = getInsets(rootView)
val croppedMap = Bitmap.createBitmap(
screenBitmap, 0, heightDifference,
screenBitmap.width,
screenBitmap.height - heightDifference)
val blurredScreen = blurBitmap(croppedMap)
if (blurredScreen != null) {
val myDrawable = BitmapDrawable(a!!.resources, blurredScreen)
a.errorHudFrameLayout?.background = myDrawable
a.appBarLayout?.visibility = View.INVISIBLE
}
}
그리고 활동 수업에서 :
fun blurView() {
this.runOnUiThread {
Helper.blurView(this)
}
}
물론 정적 헬퍼 클래스 메소드 매개 변수에 대한 활동에 대한 약한 참조를 전달하려고하지만 간결성을 위해이 예제에서는 자제했습니다. blurBitmap
과는 errorHudFrameLayout
그들이 직접적으로 상태 바의 높이를 구하는 방법에 관계하지 않기 때문에, 마찬가지의 이유로 생략하고있다.
두 가지 최고의 솔루션을 결합한 Kotlin 버전
fun getStatusBarHeight(): Int {
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
return if (resourceId > 0) resources.getDimensionPixelSize(resourceId)
else Rect().apply { window.decorView.getWindowVisibleDisplayFrame(this) }.top
}
status_bar_height
존재하는 경우 가치를status_bar_height
없는, 장식 창문에서 상태 막대의 높이를 계산