Chiều cao của thanh trạng thái trong Android


332

Chiều cao của thanh trạng thái trong Android là bao nhiêu? Có phải nó luôn giống nhau không?

Từ các phép đo của tôi, có vẻ như đó là 25dp, nhưng tôi không chắc liệu nó có cùng chiều cao trên tất cả các nền tảng hay không.

(Tôi muốn biết điều này để thực hiện đúng cách chuyển đổi mờ dần từ một hoạt động không có thanh trạng thái sang hoạt động đó)


Nếu bạn làm mờ dần thì bạn sẽ không cần biết chiều cao của thanh trạng thái.
tàng hình

2
Tôi cần nó bởi vì một số yếu tố được tập trung trong bố cục, và tôi sẽ làm cho chúng mờ dần vào nhau.
hpique

Câu trả lời:


363

Câu hỏi này đã được trả lời trước ... Chiều cao của thanh trạng thái?

Cập nhật ::

Phương pháp hiện tại:

ok, chiều cao của thanh trạng thái phụ thuộc vào kích thước màn hình, ví dụ: trong thiết bị có kích thước màn hình 240 X 320, chiều cao của thanh trạng thái là 20px, đối với thiết bị có kích thước màn hình 320 X 480, chiều cao của thanh trạng thái là 25px, đối với thiết bị có 480 x 800 chiều cao thanh trạng thái phải là 38px

Vì vậy, tôi khuyên bạn nên sử dụng tập lệnh này để có được chiều cao của thanh trạng thái

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); 

(Phương pháp cũ) để lấy Chiều cao của thanh trạng thái trên onCreate()phương thức Hoạt động của bạn, hãy sử dụng phương pháp này:

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

Không chính xác. Tôi cũng đang hỏi liệu tôi có thể cho rằng thanh trạng thái có cùng chiều cao trong tất cả các thiết bị không.
hpique

16
Hay dùng nhúng? Nếu nó luôn có 25dip thì mã không cần thiết.
hpique

8
bạn không thể cho rằng nó luôn luôn là 25dp (ví dụ: kiểm tra chiều cao trên ngọn lửa).
DallinDyer

1
Không hoạt động trong runnable được chuyển đến view.post () trong onCreate () - return 0
Ixx

4
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)không phải là một cách chính xác để có được chiều cao của thanh trạng thái nếu bạn ở chế độ nhiều cửa sổ + xoay dọc + cửa sổ thứ hai. Bạn sẽ nhận được một giá trị rất lớn (bao gồm chiều cao thứ 1).
Tuần Châu

211

Trong số tất cả các mẫu mã tôi đã sử dụng để lấy chiều cao của thanh trạng thái, chỉ có một mẫu thực sự hoạt động theo onCreatephương pháp của một Activitylà:

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

Rõ ràng chiều cao thực tế của thanh trạng thái được giữ dưới dạng tài nguyên Android. Đoạn mã trên có thể được thêm vào một ContextWrapperlớp (ví dụ: một Activity).

Tìm thấy tại http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/


Thay vì mã hóa cứng, tốt hơn là tính toán linh hoạt. Phương pháp trên làm việc cho tôi!
nhà giả kim

bạn không nên sử dụng getDimension (...) chứ?
nhà phát triển Android

6
Một lời cảnh báo - điều này không hoạt động trên tất cả các thiết bị. Ví dụ: trên Transformer TF201 (cũng như TF101, TF300 và một số thiết bị khác) chiều cao được báo cáo là 25 khi không có thanh trạng thái.
Błażej Czapp

4
Dựa trên các nhận xét ở trên, dường như mã này đang cho bạn biết chiều cao của thanh trạng thái trên một thiết bị cụ thể - không phải là gì trên một hoạt động cụ thể (có thể không thực sự có thanh trạng thái).
bàng hoàng

trong XML, tài nguyên dimen "@android: dimen / status_bar_height" có thể được sử dụng. <! - Chiều cao của thanh trạng thái được xác định trong tệp nguồn hệ thống Android -> <dimen name = "status_bar_height"> 24dp </ dimen>. Nhưng bạn không thể tham chiếu trực tiếp nó trong dự án ứng dụng của bạn. Vì vậy, bạn phải sử dụng mã.
Tshunglee

48

Trên các thiết bị MDPI, thanh trạng thái là 25px. Chúng ta có thể sử dụng nó làm cơ sở và nhân nó với mật độ (làm tròn lên) để có được chiều cao thanh trạng thái trên bất kỳ thiết bị nào:

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

Để tham khảo: ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2


6
Điều này đúng với các thiết bị thanh trạng thái. Lưu ý rằng vì những điều trên đã được viết, nên không phải tất cả các thiết bị đều có một cái đúng. Cụ thể, các thiết bị chạy ICS có thể có thanh trạng thái / thanh điều hướng kết hợp ở phía dưới và không có gì ở trên cùng. Vì vậy, trong trường hợp đó, đối với hầu hết các mục đích lập trình, bạn sẽ muốn gán chiều cao bằng 0 cho thanh trạng thái, nhưng công thức trên sẽ cung cấp cho bạn một kích thước khác không.
Carl

1
Ngoài ra, giá trị 25px không đúng với tất cả các thiết bị mdpi. Nó có thể thay đổi dựa trên cấp độ API. Ví dụ: thiết bị giả lập máy tính bảng 10.1 WXGA báo cáo 25px ở API 16 & 19, nhưng 24px ở API 24.
jk7 26/07/17

Cái này có hoạt động với pinhole's và notch không?
xử

48

Mã hóa kích thước hoặc sử dụng sự phản chiếu để có được giá trị status_bar_heightđược coi là thực hành xấu. Chris Banes đã nói về điều này tại Droidcon New York . Cách nhận kích thước thanh trạng thái được đề xuất là thông qua OnApplyWindowInsetsListener :

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

Điều này đã được thêm vào API 20 và cũng được nhập lại thông qua ViewAppCompat .


Đây là câu trả lời chính xác nhất hiện nay
keith

Đối với tôi điều này chỉ bắn một lần, Nếu tôi có mảnh vỡ thông qua điều hướng dưới cùng. Nếu tôi thay thế đoạn đó một lần nữa, trình nghe này không được gọi, liệu có một compat getter nào không?
urSus

73
Nhưng API này thật kinh khủng, vì số lượng WTF / Gotchas đằng sau hậu trường là rất lớn. Bạn sẽ nghĩ rằng bạn có thể làm điều đó với bất kỳ chế độ xem nào, nhưng không, bạn cần ghi đè một số điều nhất định và đảm bảo BẠN chuyển các nội dung cho con bạn (??) vì MỘT SỐ Viewgroup sẽ (thiết kế vật liệu) và TẤT CẢ CÁC NGƯỜI KHÁC sẽ không ( bố trí tuyến tính? ConstraintLayout? xin chào?). Thay vì hệ thống có Window.getStatusBarSize () thì chúng ta phải ĐĂNG KÝ DANH SÁCH MỘT DANH SÁCH FREAKING về nhà Android, bạn đang say. Chỉ cần mã hóa kích thước cho đến khi Google thức dậy, chúng tôi sẽ vào năm 2018. Tôi hy vọng Chris Banes sẽ thấy một ngày này
Martin Marconcini

Trong trường hợp của tôi, nó không bị sa thải. Tôi đặt nó Hoạt động # onCreated. Tôi đã làm gì sai sao? Ngoài ra, tại sao chúng ta không sử dụng mView.getRootWindowInsets ()?
Adil Aliyev

34

Tôi đã hợp nhất một số giải pháp với nhau:

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

một cách khác:

    final View view = findViewById(android.R.id.content);
    runJustBeforeBeingDrawn(view, new Runnable() {
        @Override
        public void run() {
            int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
        }
    });

EDIT: Thay thế cho runJustB BeforeByingDrawn: https://stackoverflow.com/a/28136027/878126


getResource (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight () không hoạt động trong android lolipop
abbasalim

@ ArMo372 Câu trả lời cập nhật. Chỉ là quan điểm cần phải vượt qua phép đo trước tiên. Bạn không cần phải sử dụng runJustB BeforeByingDrawn nếu bạn đã vượt qua nó. Bạn sẽ chỉ sử dụng nó trong các trường hợp quá sớm.
nhà phát triển Android

28

Theo hướng dẫn thiết kế của Google ; chiều cao của thanh trạng thái là 24 dp.

Nếu bạn muốn có chiều cao thanh trạng thái tính bằng pixel, bạn có thể sử dụng phương pháp bên dưới:

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

có thể được gọi từ hoạt động với:

statusBarHeight(getResources());

18
Cho đến khi Marshmallow được 25dp. Kể từ Marshmallow, nó là 24dp.
Eugen Pechanec

1
về cơ bản, đây là mã hóa giá trị - không cho phép thay đổi thiết kế
siliconeagle

1
và không tính đến thực tế là thanh trạng thái sẽ không được hiển thị trong cùng trường hợp
jk7

19

Chiều cao mặc định được sử dụng là 25dp. Với Android Marshmallow (API 23), chiều cao đã giảm xuống còn 24dp.

Cập nhật: Xin lưu ý rằng từ khi tuổi của các rãnh và máy quay toàn bộ bắt đầu, việc sử dụng chiều cao tĩnh cho thanh trạng thái không còn hoạt động. Vui lòng sử dụng chèn cửa sổ thay thế!


1
ngọt! Tôi vừa tạo một dimens.xml đặc biệt cho API cấp 23+ trong đó tôi đã mã hóa chiều cao là 24dp.
Ai đó ở đâu đó

18

cái này cũng hoạt động với liên kết điều chỉnh

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

Tôi có cùng một vấn đề là phải lấy chiều cao của thanh trạng thái trong một onCreate. Điều này làm việc cho tôi.

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;

Bên trong 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;
}

Xem:

http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guferences/icon_design.html


3
Tôi thích ý tưởng của bạn về việc sử dụng các giá trị theo mật độ. Nếu bạn sẽ sử dụng mã ở nhiều nơi (hoặc sử dụng các giá trị liên quan đến mật độ khác), tôi thích giảm tải công việc cho hệ thống và lưu trữ các giá trị trong tài nguyên bị giảm, điều này khiến cho việc chuyển đổi không cần thiết. Bạn cần phải tạo một thư mục tài nguyên và tệp tài nguyên cụ thể cho từng mật độ. Tài nguyên cuối cùng res = bối cảnh.getResource (); int statusbarHeight = 0; thử {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } Catch (NotFoundException e) {}
ProjectJTHERman

5
Mã hóa các giá trị này là nguy hiểm, nếu chúng thay đổi trong phiên bản nền tảng mới thì sao?
David Snabel-Caunt

Tôi nghĩ rằng thay vì sử dụng kích thước pixel được mã hóa cứng (một cho mỗi mật độ), tốt hơn là sử dụng "25dp".
nhà phát triển Android


12

Có khi tôi dùng thử với View, nó cung cấp kết quả 25px. Đây là toàn bộ mã:

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

Đoạn mã trên hoạt động với tôi khi tôi tạo một bố cục tuyến tính mới như bạn đã làm ở trên, nhưng khi tôi tìm findviewbyid cho lySpin từ xml. sau đó nó trả về null. không hiểu y nó đang cư xử như vậy.
Shaista Naaz

Bởi vì bố cục không biết kích thước của nó trong onCreate vì nó chưa được vẽ xong. Những gì tôi thường làm là đăng một Runnable trên luồng UI từ onCreate, cho phép UI có thời gian để tự vẽ.
Jason Robinson

8

240x320 - 20px

320x480 - 25px

480x800 + - 38px


3
Điều này không còn chính xác. Sử dụng phương pháp đo thanh trạng thái.
Michael

7

Thử cái này:

    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 );

nó không hoạt động với tôi trong phương thức onCreate cho hoạt động, nhưng đã làm khi tôi đưa nó vào onClickListener và cho tôi số đo 25


Tôi nghi ngờ rằng tại thời điểm anh ta thử nghiệm trên onCreate (), thanh trạng thái chưa được tạo. Ngược lại, khi anh nhấp vào thủ công để kích hoạt mã onClickListener () của mình, thanh đã có nhiều thời gian kiểu suy nghĩ để hiển thị và anh có thể truy xuất kích thước của nó.
Carl

6

chiều cao của thanh trạng thái là 24dp trong Android 6.0

 <!-- 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>

bạn có thể tìm thấy câu trả lời trong mã nguồn: frameworks \ base \ core \ res \ res \ value \ dimens.xml


có cách nào để có được tài nguyên này trong các XML của chúng tôi không? @android:dimen/status_bar_heightkhông làm việc cho tôi
Patrick

4

Để giải quyết điều này, tôi đã sử dụng một phương pháp kết hợp. Điều này là cần thiết vì trên máy tính bảng, thanh hệ thống đã trừ các pixel của nó khi display.getHeight () được gọi. Vì vậy, trước tiên tôi kiểm tra xem một thanh hệ thống có mặt hay không, và sau đó là cách tiếp cận của Ben Claytons, hoạt động tốt trên điện thoại.

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

Nhờ @Niklas +1, đây là cách chính xác để làm điều đó.

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;
    }
}

Xin thứ lỗi cho tôi nếu mã không chính xác 100%, đã chuyển đổi nó từ Xamarin C # nhưng đây chỉ là mã của nó. Hoạt động với Notches, vv


2

Giải pháp toàn màn hình Toggled:

Giải pháp này có thể trông giống như một cách giải quyết, nhưng nó thực sự tính đến việc ứng dụng của bạn có ở chế độ toàn màn hình hay không (còn ẩn thanh trạng thái) hay không:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();

Bằng cách này, nếu ứng dụng của bạn hiện ở chế độ toàn màn hình, barheightsẽ bằng 0.

Cá nhân tôi đã phải sử dụng điều này để sửa tọa độ TouchEvent tuyệt đối để tính đến thanh trạng thái như sau:

@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());
}

Và điều đó sẽ có được tọa độ y tuyệt đối cho dù ứng dụng có toàn màn hình hay không.

Thưởng thức


Cảm ơn, đây là giải pháp duy nhất hiệu quả với tôi khi bàn phím android cũng hiển thị.
Thiago Moura

2

Trên Android 4.1 trở lên, bạn có thể đặt nội dung của ứng dụng xuất hiện phía sau thanh trạng thái để nội dung không thay đổi kích thước khi thanh trạng thái ẩn và hiển thị. Để thực hiện việc này, hãy sử dụng HỆ THỐNG_UI_FLAG_LAYOUT_FULLSCREEN. Bạn cũng có thể cần sử dụng HỆ THỐNG_UI_FLAG_LAYOUT_STABLE để giúp ứng dụng của bạn duy trì bố cục ổn định.

Khi bạn sử dụng phương pháp này, bạn có trách nhiệm đảm bảo rằng các phần quan trọng trong giao diện người dùng của ứng dụng của bạn (ví dụ: các điều khiển tích hợp trong ứng dụng Bản đồ) sẽ không bị che bởi các thanh hệ thống. Điều này có thể làm cho ứng dụng của bạn không thể sử dụng được. Trong hầu hết các trường hợp, bạn có thể xử lý việc này bằng cách thêm thuộc tính android: fitSystemWindows vào tệp bố cục XML của bạn, được đặt thành đúng. Điều này điều chỉnh phần đệm của Viewgroup cha để chừa không gian cho các cửa sổ hệ thống. Điều này là đủ cho hầu hết các ứng dụng.

Tuy nhiên, trong một số trường hợp, bạn có thể cần sửa đổi phần đệm mặc định để có bố cục mong muốn cho ứng dụng của mình. Để trực tiếp thao tác làm thế nào nội dung của bạn có liên quan đến các thanh hệ thống (chiếm một khoảng trống được gọi là "nội dung" của cửa sổ), hãy ghi đè fitSystemWindows (Rect insets). Phương thức fitSystemWindows () được gọi bởi hệ thống phân cấp khung nhìn khi nội dung chèn cho một cửa sổ đã thay đổi, để cho phép cửa sổ điều chỉnh nội dung của nó cho phù hợp. Bằng cách ghi đè phương thức này, bạn có thể xử lý các phần tử (và do đó bố cục của ứng dụng) theo cách bạn muốn.

biểu mẫu: https://developer.android.com/training/system-ui/status.html#behind


1

Nếu bạn biết chính xác kích thước chiều cao VS

giống

ví dụ: trong thiết bị có kích thước màn hình 320 X 480, chiều cao của thanh trạng thái là 25px, đối với thiết bị có 480 x 800, chiều cao của thanh trạng thái phải là 38px

sau đó bạn có thể chỉ cần lấy chiều rộng của chế độ xem / kích thước màn hình, bạn chỉ có thể sử dụng câu lệnh if khác để lấy chiều cao của thanh trạng thái


Theo kinh nghiệm của tôi, chiều cao dường như dựa trên mật độ chứ không phải kích thước màn hình. Tất nhiên, mật độ bản thân nó thường liên quan đến kích thước màn hình, do đó có một mối quan hệ gián tiếp. Chẳng hạn, chiếc Moto Droid cũ của tôi có màn hình 480x854 (chứ không phải 480x800) và thanh trạng thái cũng cao 38 pixel.
Carl

Họ đã phát minh ra dp cho điều này (mật độ pixel độc lập)
Roel

1

Lý do tại sao câu trả lời hàng đầu không hoạt động đối với một số người là vì bạn không thể có được kích thước của chế độ xem cho đến khi nó sẵn sàng hiển thị. Sử dụng một OnGlobalLayoutListenerđể có được kích thước nói khi bạn thực sự có thể:

@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
        }
    }
}

Đây là phương pháp đáng tin cậy nhất.


1
@androiddeveloper OnGlobal! = GlobalOn
marijnz0r

@ marijnz0r Thật kỳ quặc. Làm thế nào để đối phó với nó đây?
nhà phát triển Android

@androiddeveloper Tôi không biết, nhưng tôi cũng nghĩ giống như bạn đã làm vài ngày trước. Xem: stackoverflow.com/a/19216041/4587214
marijnz0r

@ marijnz0r Vậy cả hai đều làm như vậy. Nhắc nhở tôi về các trường hợp khác rằng họ đã đặt tên mới cho một thứ đã tồn tại và không dùng nữa. Ví dụ "fill_parent" so với "match_parent": developer.android.com/reference/android/view/
nhà phát triển Android

1

Vì chế độ đa cửa sổ hiện có sẵn, ứng dụng của bạn có thể không có thanh trạng thái trên đầu.

Giải pháp sau đây xử lý tất cả các trường hợp tự động cho bạn.

android:fitsSystemWindows="true"

hoặc lập trình

findViewById(R.id.your_root_view).setFitsSystemWindows(true);

bạn cũng có thể nhận được root xem

findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)

Để biết thêm chi tiết về cách xem root, hãy tham khảo - https://stackoverflow.com/a/4488149/9640177


0

Vấn đề này gần đây đã trở nên phù hợp với tôi vì phần notch trong Pixel 3x của tôi. Tôi thực sự thích giải pháp của nhà phát triển Android , nhưng tôi muốn có thể có được chiều cao của thanh trạng thái theo ý muốn, vì nó đặc biệt cần thiết cho hoạt hình toàn màn hình mà tôi cần chơi. Các chức năng dưới đây cho phép một truy vấn đáng tin cậy:

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
   }
}

Và sau đó trong lớp hoạt động:

fun blurView() {
    this.runOnUiThread {
        Helper.blurView(this)
    }
}

Tất nhiên bạn sẽ muốn chuyển một tham chiếu yếu của hoạt động sang tham số phương thức lớp Helper tĩnh, nhưng vì lý do ngắn gọn, tôi đã kiềm chế trong ví dụ này. Các blurBitmaperrorHudFrameLayoutbị bỏ qua vì lý do tương tự, vì chúng không liên quan trực tiếp đến việc thu thập chiều cao của thanh trạng thái.


Nếu nó dành cho Android P trở lên, tại sao phải kiểm tra với Android M? Ngoài ra, bạn sẽ làm gì nếu bạn không có phiên bản View? Ví dụ: nếu bạn hiện không có Hoạt động ...
nhà phát triển Android

M là sớm nhất mà bạn có thể kiểm tra ổn địnhInsetTop và mặc dù chỉ có P hỗ trợ các notch tôi muốn có được phần thực tế có thể thay vì trở về mặc định nơi tôi có thể. Giải pháp này không hoạt động nếu bạn không có hoạt động.
James Jordan Taylor

Tôi hiểu rồi. Cảm ơn bạn. Bạn có thể vui lòng cho thấy một ví dụ "đầy đủ" hơn?
nhà phát triển Android

Tôi đã thay đổi câu trả lời của tôi ở trên để sử dụng phương pháp trong một ví dụ.
James Jordan Taylor

Tôi có nghĩa là một ví dụ làm việc, nhưng ok.
nhà phát triển Android

0

Phiên bản Kotlin kết hợp hai giải pháp tốt nhất

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. Nhận status_bar_height giá trị nếu có
  2. Nếu status_bar_heightkhông có, tính toán chiều cao thanh trạng thái từ Cửa sổ trang trí
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.