Android의 상태 표시 줄 높이


332

Android에서 상태 표시 줄의 높이는 얼마입니까? 항상 같은가요?

내 측정 결과 25dp 인 것처럼 보이지만 모든 플랫폼에서 높이가 같은지 확실하지 않습니다.

(상태 표시 줄이없는 활동에서 그렇지 않은 활동으로 페이드 전환을 올바르게 구현하려면 이것을 알고 싶습니다.)


크로스 페이드를 수행하면 상태 표시 줄의 높이를 알 필요가 없습니다.
— stealthcopter 16:04의

2
일부 요소가 레이아웃의 중심에 있기 때문에 필요하며 서로 페이드되도록합니다.
— hpique

답변:


363

이 질문은 전에 답변되었습니다 ... 상태 표시 줄의 높이?

업데이트 ::

현재 방법 :

예, 상태 표시 줄의 높이는 화면 크기에 따라 다릅니다 (예 : 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;
} 

정확히. 또한 모든 장치에서 상태 표시 줄의 높이가 같다고 가정 할 수 있는지 묻습니다.
— hpique

16
아니면 딥을 사용합니까? 항상 25dip이면 코드가 필요하지 않습니다.
— hpique

8
항상 25dp라고 가정 할 수는 없습니다 (예를 들어 킨들 화재의 높이를 확인하십시오).
— DallinDyer

1
onCreate ()에서 view.post ()에 전달 된 실행 가능에서 작동하지 않음-0을 반환
— Ixx

4
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)다중 창 모드 + 세로 회전 + 두 번째 창에있는 경우 상태 표시 줄 높이를 얻는 올바른 방법이 아닙니다. 큰 값을 얻습니다 (첫 번째 높이 포함).
— Tuan Chau

211

상태 표시 줄의 높이를 얻는 데 사용한 모든 코드 샘플 중에서 실제로 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/ 에서 발견


하드 코딩 대신 동적으로 계산하는 것이 좋습니다. 위의 방법은 저에게 효과적이었습니다!
— 연금술사

getDimension (...)을 대신 사용해서는 안됩니까?
— 안드로이드 개발자

6
주의 사항-일부 기기에서는 작동하지 않습니다. 예를 들어 Transformer TF201 (TF101, TF300 및 기타 장치)에서 높이는 상태 표시 줄이없는 경우 25로보고됩니다.
— Błażej Czapp

4
위의 의견을 바탕으로 코드는 특정 활동에 대한 상태 표시 줄의 높이가 아닌 특정 장치에 대한 상태 표시 줄의 높이를 알려줍니다 (실제 상태 표시 줄이 없을 수도 있음).
— 혼란스러워

XML에서 dimen 리소스 "@android : dimen / status_bar_height"를 사용할 수 있습니다. <!-안드로이드 시스템 소스 파일에 정의 된 상태 표시 줄의 높이-> <dimen name = "status_bar_height"> 24dp </ dimen>. 그러나 앱 프로젝트에서 직접 참조 할 수는 없습니다. 따라서 코드를 사용해야합니다.
— Tshunglee

48

MDPI 장치에서 상태 표시 줄은 25px입니다. 이것을 기본으로 사용하고 밀도 (반올림)를 곱하여 모든 장치에서 상태 표시 줄 높이를 얻을 수 있습니다.

int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);

참조 : ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2


6
상태 표시 줄 이 있는 장치에 적합합니다 . 위의 내용을 기록한 이후 모든 장치에 장치가있는 것은 아니라는 점에 유의하십시오. 특히, ICS를 실행하는 장치는 하단에 결합 된 상태 / 탐색 막대가 있고 상단에는 전혀 없습니다. 따라서 대부분의 프로그래밍 목적으로 상태 표시 줄에 높이를 0으로 지정하려고하지만 위의 공식은 0이 아닌 크기를 제공합니다.
— Carl

1
또한 25px 값이 모든 mdpi 장치에 올바른 것은 아닙니다. API 수준에 따라 달라질 수 있습니다. 예를 들어, 10.1 WXGA 태블릿 에뮬레이터 장치는 API 16 및 19에서 25px, API 24에서 24px를보고합니다.
— jk7

48

크기를 하드 코딩하거나 리플렉션을 사용하여 값을 얻는 것은 status_bar_height나쁜 습관으로 간주됩니다. Chris Banes 는 Droidcon New York에서 이에 대해 이야기했습니다 . 상태 표시 줄 크기를 얻는 권장 방법은 OnApplyWindowInsetsListener 를 사용하는 것입니다 .

myView.setOnApplyWindowInsetsListener { view, insets -> {
  val statusBarSize = insets.systemWindowInsetTop
  return insets
}

이것은 API 20에 추가되었으며 ViewAppCompat 를 통해 백 포트됩니다 .


이것은 오늘 가장 정확한 답변입니다.
— keith

나를 위해 이것은 바닥 탐색을 통해 조각이있는 경우 한 번만 발생합니다. 프래그먼트를 다시 교체하면이 리스너가 호출되지 않습니다 .Compat getter도 있습니까?
— urSus

74
그러나이 API는 끔찍한 데, 그 이유는 무대 뒤의 WTF / Gotcha가 많기 때문입니다. 어떤 뷰에서든 할 수 있다고 생각할 수는 없지만 특정 뷰를 무시하고 일부 뷰 그룹이 (재료 설계)하고 모든 다른 사람들이 ( 선형 레이아웃? ConstraintLayout? hello?). Window.getStatusBarSize ()가있는 시스템 대신… 우리는 별다른 어려움을 겪지 말고 집에 가라. Google이 깨어날 때까지 크기를 하드 코딩하면 2018 년이됩니다. Chris Banes가이 날을 보게되기를 바랍니다…
— Martin Marconcini 2016 년

제 경우에는 해고되지 않습니다. Activity # onCreated에 넣었습니다. 내가 뭐 잘못 했어요? 또한 왜 mView.getRootWindowInsets ()를 사용하지 않습니까?
— Adil Aliyev

34

몇 가지 솔루션을 병합했습니다.

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


getResources (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight ()가 안드로이드 lolipop에서 작동하지 않음
— abbasalim

@ ArMo372 업데이트 된 답변입니다. 뷰가 측정을 먼저 통과해야한다는 것입니다. 이미 통과 한 경우 runJustBeforeBeingDrawn을 사용할 필요가 없습니다. 너무 이른 경우에만 사용합니다.
— 안드로이드 개발자

28

구글 디자인 가이드 라인 에 따르면 ; 상태 표시 줄의 높이는 24dp입니다.

상태 표시 줄 높이를 픽셀 단위로 얻으려면 아래 방법을 사용할 수 있습니다.

private static int statusBarHeight(android.content.res.Resources res) {
    return (int) (24 * res.getDisplayMetrics().density);
}

다음을 사용하여 활동에서 호출 할 수 있습니다.

statusBarHeight(getResources());

18
마시멜로까지 그것은 25dp였다. 마시멜로 이후 24dp입니다.
— Eugen Pechanec

1
이것은 본질적으로 값을 하드 코딩하는 것입니다. – 디자인 변경을 허용하지 않습니다
— siliconeagle

1
상태 표시 줄이 같은 경우에 표시되지 않는다는 사실을 설명하지 않습니다
— jk7

19

기본 높이는 25dp였습니다. Android Marshmallow (API 23)에서는 높이가 24dp로 줄었습니다.

업데이트 : 노치 및 펀치 전체 카메라의 시대가 시작되었으므로 상태 표시 줄의 정적 높이를 사용하면 더 이상 작동하지 않습니다. 대신 창 삽입을 사용하십시오!


1
단! 방금 높이를 24dp로 하드 코딩 한 API 레벨 23 이상을 위해 dimens.xml을 만들었습니다.
— 누군가 어딘가에

18

이것은 또한 refrence 링크 와 함께 작동 합니다

public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
  if (resourceId > 0) {
      result = getResources().getDimensionPixelSize(resourceId);
  }
  return result;
}

13

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


3
밀도 중심 값을 사용하려는 아이디어가 마음에 듭니다. 여러 곳에서 코드를 사용하거나 다른 밀도 관련 값을 사용하려는 경우 작업을 시스템으로 오프로드하고 값을 dimen 리소스에 저장하여 스위치를 불필요하게 만듭니다. 각 밀도에 대한 차원 별 폴더 및 리소스 파일을 만들어야합니다. 최종 자원 res = context.getResources (); int statusbarHeight = 0; 시도 {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } catch (NotFoundException e) {}
— ProjectJourneyman

5
이 값을 하드 코딩하는 것은 위험합니다. 이후 플랫폼 버전에서 변경되면 어떻게됩니까?
— David Snabel-Caunt

하드 코딩 된 픽셀 크기 (각 밀도마다 하나씩)를 사용하는 대신 "25dp"를 사용하는 것이 좋습니다.
— 안드로이드 개발자


12

예, 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);
            }
        }
    }
}

위의 코드는 위에서 한 것처럼 새 선형 레이아웃을 만들 때 xml에서 lySpin에 대해 findviewbyid를 수행 할 때 작동합니다. 그런 다음 null을 반환합니다. 이해하지 못하고 그렇게 행동하고 있습니다.
— Shaista Naaz

레이아웃은 아직 완성되지 않았기 때문에 onCreate에서 크기를 알지 못하기 때문입니다. 내가 일반적으로하는 일은 onCreate의 UI 스레드에 Runnable을 게시하여 UI 자체를 그릴 시간을줍니다.
— Jason Robinson

8

240x320-20 픽셀

320x480-25px

480x800 +-38px


3
더 이상 정확하지 않습니다. 상태 표시 줄을 측정하는 방법을 사용하십시오.
— Michael

7

이 시도:

    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의 측정을주었습니다.


그가 onCreate ()에서 테스트 한 시점에서 상태 표시 줄이 아직 생성되지 않았다고 생각합니다. 반대로, 수동으로 클릭하여 onClickListener () 코드를 활성화하면 막대에 이미 표시 할 생각 유형 시간이 많았으며 크기를 검색 할 수있었습니다.
— Carl

6

안드로이드 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


이 리소스를 XML로 가져올 수있는 방법이 있습니까? @android:dimen/status_bar_height나를 위해 작동하지 않습니다
— Patrick

4

이 문제를 해결하기 위해 조합 접근법을 사용했습니다. 이것은 태블릿에서 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;
}

3

@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 #에서 코드를 변환했지만 이것이 바로 그 것입니다. 노치 등과 함께 작동


2

전체 화면 솔루션 전환 :

이 솔루션은 해결 방법처럼 보이지만 실제로는 앱이 전체 화면 (상태 표시 줄 숨기기)인지 여부를 설명합니다.

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 좌표를 얻습니다.

즐겨


고마워, 이것은 안드로이드 키보드가 보여 질 때 나를 위해 일한 유일한 솔루션이었습니다.
— Thiago Moura

2

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


1

크기 VS 높이를 정확히 알고 있다면

처럼

예를 들어 320 x 480 화면 크기의 기기에서는 상태 표시 줄 높이가 25 픽셀이고 480 x 800 인 기기의 경우 상태 표시 줄 높이는 38 픽셀이어야합니다.

그런 다음 뷰 너비 / 화면 크기를 얻을 수 있습니다 .if else 문을 사용하여 상태 표시 줄의 높이를 얻을 수 있습니다


내 경험상 높이는 화면 크기가 아닌 밀도를 기준으로 나타납니다. 물론 밀도 자체는 일반적으로 화면 크기와 관련이 있으므로 간접적 인 관계가 있습니다. 예를 들어, 나의 오래된 모토 드로이드는 480x854 (480x800이 아닌) 디스플레이를 가지고 있으며 상태 표시 줄의 높이는 38 픽셀입니다.
— Carl

그들은 이것을 위해 dp를 발명했다 (밀도 독립 픽셀)
— Roel

1

일부 사람들에게 최고 답변이 작동하지 않는 이유는 렌더링 준비가 될 때까지 뷰의 크기를 얻을 수 없기 때문입니다. 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
        }
    }
}

이것이 가장 안정적인 방법입니다.


1
@androiddeveloper OnGlobal! = GlobalOn
— marijnz0r

@ marijnz0r 얼마나 이상한가. 그게 무슨 거래 야?
— 안드로이드 개발자

@androiddeveloper 모르겠지만 며칠 전과 똑같은 생각을했습니다. 참조 : stackoverflow.com/a/19216041/4587214
— marijnz0r

@ marijnz0r 그래서 둘 다 동일합니다. 다른 경우에는 이미 존재하는 물건에 대해 새로운 이름을 부여하고 이전 이름은 더 이상 사용하지 않는다는 것을 상기시킵니다. 예 : "fill_parent"vs "match_parent": developer.android.com/reference/android/view/…
— Android 개발자

1

현재 다중 창 모드를 사용할 수 있으므로 앱의 상태 표시 줄이 맨 위에 표시되지 않을 수 있습니다.

다음 솔루션은 모든 사례를 자동으로 처리합니다.

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을 참조 하십시오.


0

이 문제는 최근 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그들이 직접적으로 상태 바의 높이를 구하는 방법에 관계하지 않기 때문에, 마찬가지의 이유로 생략하고있다.


Android P 이상인 경우 Android M을 확인하는 이유는 무엇입니까? 또한 View 인스턴스가 없으면 어떻게 하시겠습니까? 예를 들어 현재 활동이없는 경우 ...
— android developer

M은 당신이 stableInsetTop을 확인할 수있는 가장 빠른 것입니다 .P를 지원하는 노치만이더라도 가능한 기본값으로 돌아가는 대신 실제 삽입이 가능합니다. 활동이 없으면이 솔루션이 작동하지 않습니다.
— James Jordan Taylor

내가 참조. 감사합니다. 좀 더 "전체"예를 보여 주시겠습니까?
— 안드로이드 개발자

예제에서 메소드를 사용하도록 위의 답변을 변경했습니다.
— James Jordan Taylor

0

두 가지 최고의 솔루션을 결합한 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
}
  1. 소요 status_bar_height존재하는 경우 가치를
  2. 경우 status_bar_height없는, 장식 창문에서 상태 막대의 높이를 계산
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.