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.