Ketinggian bilah status di Android

332

Berapa ketinggian bilah status di Android? Apakah selalu sama?

Dari pengukuran saya sepertinya 25dp, tapi saya tidak yakin apakah itu memiliki ketinggian yang sama di semua platform.

(Saya ingin tahu ini untuk mengimplementasikan transisi fade dari aktivitas yang tidak memiliki status bar ke yang benar)

hpique
sumber
Jika Anda melakukan cross fade maka Anda tidak perlu tahu ketinggian bilah status.
stealthcopter
2
Saya memang membutuhkannya karena beberapa elemen berpusat di tata letak, dan saya ingin mereka memudar satu sama lain.
hpique
mungkin duplikat Tinggi statusbar?
molnarm

Jawaban:

363

pertanyaan ini dijawab sebelum ... Tinggi statusbar?

Perbarui ::

Metode saat ini:

ok, ketinggian bilah status tergantung pada ukuran layar, misalnya pada perangkat dengan ukuran layar 240 X 320 tinggi bilah status adalah 20px, untuk perangkat dengan ukuran layar 320 X 480 tinggi bilah status adalah 25px, untuk perangkat dengan 480 x 800 tinggi status bar harus 38px

jadi saya sarankan untuk menggunakan skrip ini untuk mendapatkan ketinggian bilah status

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

(Metode lama) untuk mendapatkan Ketinggian bilah status pada onCreate()metode Aktivitas Anda, gunakan metode ini:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
} 
Jorgesys
sumber
Tidak persis. Saya juga bertanya apakah saya dapat berasumsi bahwa bilah status memiliki ketinggian yang sama di semua perangkat.
hpique
16
Atau gunakan celup? Jika selalu memiliki 25dip maka kode tidak diperlukan.
hpique
8
Anda tidak dapat menganggap itu selalu 25dp (lihat ketinggian misalnya pada menyalakan api).
DallinDyer
1
Tidak berfungsi pada runnable yang diteruskan ke view.post () di onCreate () - return 0
Ixx
4
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)bukan cara yang benar untuk mendapatkan ketinggian bilah status jika Anda berada dalam mode multi-jendela + rotasi potret + jendela kedua. Anda akan mendapatkan nilai yang sangat besar (termasuk ketinggian 1).
Tuan Chau
211

Dari semua contoh kode yang saya gunakan untuk mendapatkan ketinggian bilah status, satu-satunya yang benar-benar berfungsi dalam onCreatemetode Activityadalah:

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

Rupanya ketinggian sebenarnya dari bilah status disimpan sebagai sumber daya Android. Kode di atas dapat ditambahkan ke ContextWrapperkelas (mis. An Activity).

Ditemukan di http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

Ben Clayton
sumber
Daripada mengkodekannya, lebih baik menghitung secara dinamis. Metode di atas bekerja untuk saya!
alkemis
bukankah seharusnya Anda menggunakan getDimension (...)?
pengembang android
6
Sebuah kata peringatan - ini tidak bekerja pada semua perangkat. Misalnya pada Transformer TF201 (serta TF101, TF300 dan beberapa perangkat lainnya) tingginya dilaporkan 25 di mana tidak ada status bar.
Błażej Czapp
4
Berdasarkan komentar di atas, tampaknya bagi saya bahwa kode memberi tahu Anda apa ketinggian bilah status pada perangkat tertentu - bukan apa itu pada aktivitas tertentu (yang mungkin sebenarnya tidak memiliki bilah status).
Bingung
dalam XML sumber daya dimen "@android: dimen / status_bar_height" dapat digunakan. <! - Ketinggian bilah status yang ditentukan dalam file sumber sistem android -> <dimen name = "status_bar_height"> 24dp </dimen>. Tetapi Anda tidak dapat mengarahkan referensi ke proyek aplikasi Anda. Jadi, Anda harus menggunakan kode.
Tshunglee
48

Pada perangkat MDPI, bilah status adalah 25px. Kita dapat menggunakan ini sebagai basis dan mengalikannya dengan densitas (dibulatkan ke atas) untuk mendapatkan ketinggian bilah status di perangkat apa pun:

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

Untuk referensi: ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2

Grantland Mengunyah
sumber
6
Ini benar untuk perangkat yang memiliki bilah status. Perhatikan bahwa sejak tulisan di atas ditulis, menjadi kenyataan bahwa tidak semua perangkat akan memilikinya. Secara khusus, perangkat yang menjalankan ICS mungkin memiliki status gabungan / bilah nav di bagian bawah dan tidak ada sama sekali di bagian atas. Jadi untuk kasus itu, untuk sebagian besar tujuan pemrograman, Anda ingin menetapkan ketinggian nol ke bilah status, tetapi formulasi di atas akan memberi Anda ukuran bukan nol.
Carl
1
Nilai 25px juga tidak benar untuk semua perangkat mdpi. Itu dapat bervariasi berdasarkan tingkat API. Sebagai contoh, perangkat emulator tablet WXGA 10.1 melaporkan 25px pada API 16 & 19, tetapi 24px pada API 24.
jk7
48

Hardcoding ukuran atau menggunakan refleksi untuk mendapatkan nilai status_bar_heightdianggap praktik buruk. Chris Banes membicarakan hal ini di Droidcon New York . Cara yang disarankan untuk mendapatkan ukuran bilah status adalah melalui OnApplyWindowInsetsListener :

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

Ini ditambahkan dalam API 20 dan juga di-backport melalui ViewAppCompat .

Niklas
sumber
Ini adalah jawaban yang paling akurat hari ini
keith
bagi saya ini hanya sekali, jika saya memiliki fragmen melalui bottom nav. Jika saya mengganti fragmen lagi, pendengar ini tidak dipanggil, apakah ada pembuat compat juga?
urSus
74
Namun API ini mengerikan, karena jumlah WTF / Gotcha di balik layar sangat besar. Anda akan berpikir bahwa Anda dapat melakukannya dengan tampilan apa pun, tetapi tidak, Anda perlu menimpa hal-hal tertentu dan memastikan ANDA memberikan insets kepada anak-anak Anda (??) karena BEBERAPA ViewGroup akan (desain material) dan SEMUA ORANG LAIN tidak akan ( tata letak linier? ConstraintLayout? halo?). Alih-alih sistem memiliki Window.getStatusBarSize () ... kita harus BERLANGGANAN MENDENGARKAN FREAKING LISTENER ... pulang Android, Anda mabuk. Hanya hardcode ukurannya sampai Google bangun, kita di 2018. Saya harap Chris Banes melihat ini suatu hari ...
Martin Marconcini
Dalam kasus saya itu tidak dipecat. Saya menaruhnya Activity # onCreated. Apakah saya melakukan sesuatu yang salah? Selain itu mengapa kita tidak menggunakan mView.getRootWindowInsets ()?
Adil Aliyev
34

Saya telah menggabungkan beberapa solusi bersama:

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

alternatif lain:

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

EDIT: Alternatif untuk menjalankanJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

pengembang android
sumber
getResources (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight () tidak berfungsi di Android lolipop
abbasalim
@ ArMo372 Jawaban yang diperbarui. Hanya saja pandangan perlu melewati pengukuran terlebih dahulu. Anda tidak perlu menggunakan runJustBeforeBeingDrawn jika Anda sudah melewatinya. Anda hanya akan menggunakannya pada kasus yang terlalu dini.
pengembang android
28

Menurut pedoman desain Google ; ketinggian bar status adalah 24 dp.

Jika Anda ingin mendapatkan ketinggian bilah status dalam piksel, Anda dapat menggunakan metode di bawah ini:

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

yang dapat dipanggil dari aktivitas dengan:

statusBarHeight(getResources());
Rashid
sumber
18
Sampai Marshmallow itu 25dp. Karena Marshmallow 24dp.
Eugen Pechanec
1
ini pada dasarnya adalah hardcoding nilai - yang tidak memungkinkan untuk perubahan desain
siliconeagle
1
dan tidak menjelaskan fakta bahwa bilah status tidak akan ditampilkan dalam kasus yang sama
jk7
19

Ketinggian default dulu 25dp. Dengan Android Marshmallow (API 23) tingginya dikurangi menjadi 24dp.

Pembaruan: Perlu diketahui bahwa sejak jaman notch dan keseluruhan kamera mulai, menggunakan ketinggian statis untuk bilah status tidak lagi berfungsi. Silakan gunakan inset jendela sebagai gantinya!

crysxd
sumber
1
manis! Saya baru saja membuat dimens.xml khusus untuk API level 23+ di mana saya telah mengubah kodenya setinggi 24dp.
Seseorang di suatu tempat,
18

ini juga bekerja dengan tautan referensi

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

Saya memiliki masalah yang sama karena harus mendapatkan tinggi bilah status di onCreate. Ini bekerja untuk saya.

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;

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

Lihat:

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

benhylau
sumber
3
Saya suka ide Anda menggunakan nilai yang digerakkan oleh kepadatan. Jika Anda akan menggunakan kode di beberapa tempat (atau menggunakan nilai terkait kepadatan lainnya) Saya lebih suka melepas pekerjaan ke sistem, dan menyimpan nilai-nilai dalam sumber daya yang redup, yang membuat pergantian tidak perlu. Anda perlu membuat folder khusus dan file sumber daya untuk setiap kepadatan. Sumber Daya akhir res = context.getResources (); int statusbarHeight = 0; coba {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } catch (NotFoundException e) {}
ProjectJourneyman
5
Hardcoding nilai-nilai ini berbahaya, bagaimana jika mereka berubah di versi platform yang lebih baru?
David Snabel-Caunt
Saya pikir daripada menggunakan ukuran piksel hardcoded (satu untuk setiap kepadatan), lebih baik menggunakan "25dp".
Pengembang android
13

Tinggi resmi adalah 24dp, sebagaimana dinyatakan secara resmi oleh Google di laman web Desain Android .

Joaquin Iurchuk
sumber
12

Ya ketika saya mencobanya dengan Lihat itu memberikan hasil 25px. Ini seluruh kodenya:

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);
            }
        }
    }
}
Braj
sumber
Kode di atas bekerja untuk saya ketika saya membuat tata letak linier baru seperti yang telah Anda lakukan di atas, tetapi ketika saya menemukan viewviewbyid untuk lySpin dari xml. lalu mengembalikan nol. tidak mengerti kamu berperilaku demikian.
Shaista Naaz
Karena tata letak belum mengetahui ukurannya di onCreate karena belum selesai digambar. Apa yang biasanya saya lakukan adalah memposting Runnable pada utas UI dari onCreate yang memberi waktu UI untuk menggambar sendiri.
Jason Robinson
8

240x320 - 20px

320x480 - 25px

480x800 + - 38px

Denis
sumber
3
Ini tidak lagi akurat. Gunakan metode untuk mengukur bilah status.
Michael
7

Coba ini:

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

itu tidak bekerja untuk saya dalam metode onCreate untuk aktivitas, tetapi ketika saya memasukkannya ke dalam onClickListener dan memberi saya pengukuran 25

Martyn
sumber
Saya menduga bahwa pada titik ia menguji di onCreate (), status bar belum dibuat. Sebaliknya, ketika dia mengklik secara manual untuk mengaktifkan kode onClickListener (), bilah sudah memiliki banyak waktu jenis pemikiran untuk ditampilkan, dan dia dapat mengambil ukurannya.
Carl
6

ketinggian bilah status adalah 24dp di 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>

Anda dapat menemukan jawabannya di kode sumber: frameworks \ base \ core \ res \ res \ values ​​\ dimens.xml

Xiaoyuan hu
sumber
apakah ada cara untuk mendapatkan sumber ini di XML kami? @android:dimen/status_bar_heighttidak bekerja untuk saya
Patrick
4

Untuk mengatasi ini, saya menggunakan pendekatan kombinasi. Ini diperlukan karena pada tablet bilah sistem sudah mengurangi pikselnya ketika display.getHeight () dipanggil. Jadi saya pertama kali memeriksa apakah ada bilah sistem, dan kemudian pendekatan Ben Claytons, yang berfungsi dengan baik pada ponsel.

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;
}
Rutger
sumber
3

Berkat @Niklas +1 ini adalah cara yang benar untuk melakukannya.

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

Maafkan saya jika kodenya tidak 100% benar, konversikan dari Xamarin C # tetapi ini adalah haknya. Bekerja dengan Takik, dll.

Pierre
sumber
2

Solusi Layar Penuh Toggled:

Solusi ini mungkin terlihat seperti solusi, tetapi sebenarnya memperhitungkan apakah aplikasi Anda layar penuh (alias menyembunyikan bilah status) atau tidak:

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

Dengan cara ini, jika aplikasi Anda saat ini layar penuh, barheight akan sama dengan 0.

Secara pribadi saya harus menggunakan ini untuk memperbaiki koordinat TouchEvent absolut untuk memperhitungkan bilah status sebagai berikut:

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

Dan itu akan mendapatkan koordinat y mutlak apakah aplikasi fullscreen atau tidak.

Nikmati

Aaron Gillion
sumber
Terima kasih, ini adalah satu-satunya solusi yang bekerja untuk saya ketika papan ketik android juga ditampilkan.
Thiago Moura
2

Pada Android 4.1 dan lebih tinggi, Anda dapat mengatur konten aplikasi Anda agar muncul di belakang bilah status, sehingga konten tidak mengubah ukuran ketika bilah status menyembunyikan dan menunjukkan. Untuk melakukan ini, gunakan SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Anda juga mungkin perlu menggunakan SYSTEM_UI_FLAG_LAYOUT_STABLE untuk membantu aplikasi Anda mempertahankan tata letak yang stabil.

Saat Anda menggunakan pendekatan ini, menjadi tanggung jawab Anda untuk memastikan bahwa bagian-bagian penting dari UI aplikasi Anda (misalnya, kontrol bawaan dalam aplikasi Maps) tidak berakhir dicakup oleh bilah sistem. Ini bisa membuat aplikasi Anda tidak dapat digunakan. Dalam kebanyakan kasus, Anda dapat menangani ini dengan menambahkan atribut android: fitsSystemWindows ke file tata letak XML Anda, atur true. Ini menyesuaikan bantalan ViewGroup induk untuk memberikan ruang bagi sistem windows. Ini cukup untuk sebagian besar aplikasi.

Namun, dalam beberapa kasus, Anda mungkin perlu memodifikasi lapisan default untuk mendapatkan tata letak yang diinginkan untuk aplikasi Anda. Untuk memanipulasi secara langsung bagaimana konten Anda ditampilkan relatif terhadap bilah sistem (yang menempati ruang yang dikenal sebagai "insets konten" jendela), ganti fitSystemWindows (insets Rect). Metode fitSystemWindows () dipanggil oleh hierarki tampilan ketika inset konten untuk jendela telah berubah, untuk memungkinkan jendela menyesuaikan isinya. Dengan mengganti metode ini Anda dapat menangani insets (dan karenanya tata letak aplikasi Anda) seperti yang Anda inginkan.

formulir: https://developer.android.com/training/system-ui/status.html#behind

Xiaoyuan hu
sumber
1

Jika Anda tahu persis ukuran VS tinggi

Suka

misalnya dalam perangkat dengan ukuran layar 320 X 480 tinggi status bar adalah 25px, untuk perangkat dengan 480 x 800 tinggi bar status harus 38px

maka Anda hanya bisa mendapatkan lebar tampilan Anda / ukuran layar Anda hanya bisa menggunakan pernyataan if else untuk mendapatkan ketinggian bilah status

Steven Shih
sumber
Dalam pengalaman saya, ketinggian tampaknya lebih didasarkan pada kepadatan daripada ukuran layar. Tentu saja, kepadatan itu sendiri biasanya terkait dengan ukuran layar, sehingga ada hubungan tidak langsung. Moto Droid saya yang lama, misalnya, memiliki tampilan 480x854 (daripada 480x800), dan bilah status juga tinggi 38 piksel.
Carl
Mereka menemukan dp untuk ini (kerapatan piksel independen)
Roel
1

Alasan mengapa jawaban teratas tidak berfungsi untuk sebagian orang adalah karena Anda tidak bisa mendapatkan dimensi tampilan hingga siap untuk ditampilkan. Gunakan a OnGlobalLayoutListeneruntuk mendapatkan dimensi tersebut saat Anda benar-benar dapat:

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

Ini adalah metode yang paling dapat diandalkan.

pengguna1112789
sumber
1
@androiddeveloper OnGlobal! = GlobalOn
marijnz0r
@ marijnz0r Aneh sekali. Apa masalahnya dengan itu?
pengembang android
@androiddeveloper saya tidak tahu, tapi saya kebetulan berpikir sama seperti yang Anda lakukan beberapa hari yang lalu juga. Lihat: stackoverflow.com/a/19216041/4587214
marijnz0r
@ marijnz0r Jadi keduanya melakukan hal yang sama. Mengingatkan saya pada kasus-kasus lain bahwa mereka memberi nama baru untuk barang-barang yang sudah ada, dan mencela yang sebelumnya. Contoh "fill_parent" vs "match_parent": developer.android.com/reference/android/view/…
pengembang android
1

Karena mode multi-jendela tersedia sekarang, aplikasi Anda mungkin tidak memiliki bilah status di atas.

Solusi berikut menangani semua kasing secara otomatis untuk Anda.

android:fitsSystemWindows="true"

atau secara terprogram

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

Anda juga dapat memperoleh tampilan root dengan

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

Untuk detail lebih lanjut tentang mendapatkan rujukan tampilan root - https://stackoverflow.com/a/4488149/9640177

mayank1513
sumber
0

Masalah ini baru-baru ini menjadi relevan bagi saya karena takik di Pixel 3XL saya. Saya benar-benar menyukai solusi pengembang android , tetapi saya ingin bisa mendapatkan ketinggian status bar sesuai keinginan, karena itu secara khusus diperlukan untuk animasi layar penuh yang harus saya mainkan. Fungsi di bawah ini mengaktifkan kueri yang andal:

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

Dan kemudian di kelas aktivitas:

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

Anda tentu saja ingin membuat referensi yang lemah dari aktivitas ke parameter metode kelas Helper statis, tetapi demi singkatnya saya menahan diri dalam contoh ini. Itu blurBitmapdan errorHudFrameLayoutdihilangkan karena alasan yang sama, karena mereka tidak secara langsung berkaitan dengan mendapatkan ketinggian bilah status.

James Jordan Taylor
sumber
Jika itu untuk Android P dan di atasnya, mengapa memeriksa dengan Android M? Juga, apa yang akan Anda lakukan jika Anda tidak memiliki instance View? Misalnya jika Anda tidak memiliki Kegiatan saat ini ...
pengembang android
M adalah yang paling awal yang bisa Anda periksa stableInsetTop, dan meskipun hanya P yang didukung takik saya lebih suka mendapatkan inset yang sebenarnya mungkin daripada jatuh kembali ke default di mana saya bisa. Solusi ini tidak berfungsi jika Anda tidak memiliki aktivitas.
James Jordan Taylor
Saya melihat. Terima kasih. Bisakah Anda tunjukkan contoh yang lebih "lengkap"?
pengembang android
Saya mengubah jawaban saya di atas untuk menggunakan metode dalam contoh.
James Jordan Taylor
0

Versi Kotlin yang menggabungkan dua solusi terbaik

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. Dibutuhkan status_bar_height nilai jika ada
  2. Jika status_bar_heighttidak ada, hitung ketinggian bilah status dari Dekorasi jendela
Tomrozb
sumber