Высота строки состояния в Android

Какова высота строки состояния в Android? Это всегда одно и то же?

Из моих измерений кажется, что он 25dp, но я не уверен, что он имеет одинаковую высоту на всех платформах.

(Я хочу знать это, чтобы правильно реализовать переход с постепенным исчезновением из активности, у которой нет строки состояния, которая работает)

Ответ 1

на этот вопрос был дан ответ... Высота панели состояния?

Обновление::

Текущий метод:

ok, высота строки состояния зависит от размера экрана, например, в устройстве с размером экрана 240 X 320 высота строки состояния 20 пикселей, для устройства с размером экрана 320 x 480 высота строки состояния 25 пикселей, для устройства с разрешением 480 x 800 высота строки состояния должна быть 38 пикселей

поэтому я рекомендую использовать этот script для получения высоты строки состояния

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

Ответ 2

Из всех образцов кода, которые я использовал для получения высоты строки состояния, единственная, которая действительно работает в методе 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 (например, a Activity).

Найдено http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

Ответ 3

На устройствах MDPI строка состояния составляет 25 пикселей. Мы можем использовать это как основание и умножить его на плотность (округленное вверх), чтобы получить высоту строки состояния на любом устройстве:

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

Для справки: ldpi =.75, mdpi = 1, hdpi = 1.5, xhdpi = 2

Ответ 4

Жесткое кодирование размера или использование отражения для получения значения status_bar_height считается плохой практикой. Крис Бейнс говорил об этом в Droidcon New York. Рекомендуемый способ получения размера строки состояния - через OnApplyWindowInsetsListener:

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

Это было добавлено в API 20 и также портировано через ViewAppCompat.

Ответ 5

Я объединил некоторые решения вместе:

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: fooobar.com/questions/35172/...

Ответ 6

Согласно Руководства по дизайну Google; высота строки состояния составляет 24 dp.

Если вы хотите получить высоту строки состояния в пикселях, вы можете использовать метод ниже:

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

который можно вызвать из действия с помощью:

statusBarHeight(getResources());

Ответ 7

это также работает с ссылкой <

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

Ответ 8

У меня такая же проблема, как получить высоту строки состояния в 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

Ответ 9

Официальная высота 24dp, как официально заявлено Google на веб-странице Android Design.

Ответ 10

Да, когда я пытаюсь его просматривать, он дает результат 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);
            }
        }
    }
}

Ответ 11

Высота по умолчанию была 25dp. С Android Marshmallow (API 23) высота была уменьшена до 24dp.

Обновление: Пожалуйста, имейте в виду, что с тех пор, как начался возраст надрезов и камер с перфорацией, использование статической высоты для строки состояния больше не работает. Пожалуйста, используйте вместо окна вставки!

Ответ 12

240x320 - 20px

320x480 - 25px

480x800 + - 38px

Ответ 13

Попробуйте следующее:

    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

Ответ 14

высота строки состояния составляет 24dp в 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>

вы можете найти ответ в исходном коде: frameworks\base\core\res\res\values ​​\ dimens.xml

Ответ 15

Чтобы решить эту проблему, я использовал комбинированный подход. Это необходимо, так как на планшетах системная панель уже вычитает пиксели при вызове display.getHeight(). Поэтому я сначала проверяю наличие системной панели, а затем подход Бена Клейтона, который отлично работает на телефонах.

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

Ответ 16

Toggled Fullscreen Solution:

Это решение может выглядеть как обходное решение, но на самом деле это зависит от того, включено ли ваше приложение в полноэкранный режим (он же скрывает строку состояния) или нет:

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-координата, будет ли приложение полноэкранным или нет.

Enjoy

Ответ 17

В Android версии 4.1 и выше вы можете настроить содержимое своего приложения за панель состояния, чтобы содержимое не изменялось, поскольку строка состояния скрывается и отображается. Для этого используйте SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Вам также может потребоваться использовать SYSTEM_UI_FLAG_LAYOUT_STABLE, чтобы ваше приложение поддерживало стабильный макет.

Когда вы используете этот подход, вы несете ответственность за то, чтобы критические части пользовательского интерфейса вашего приложения (например, встроенные элементы управления в приложении "Карты" ) не попадали под панель системы. Это может сделать ваше приложение непригодным. В большинстве случаев вы можете справиться с этим, добавив в файл макета XML атрибут android: fitsSystemWindows, установленный в true. Это настраивает дополнение родительской ViewGroup, чтобы оставить пространство для системных окон. Этого достаточно для большинства приложений.

Однако в некоторых случаях вам может потребоваться изменить заполнение по умолчанию, чтобы получить желаемый макет для вашего приложения. Чтобы непосредственно манипулировать тем, как ваш контент располагается относительно системных баров (которые занимают пространство, известное как окно "вставки содержимого" ), переопределите fitSystemWindows (Rect insets). Метод fitSystemWindows() вызывается иерархией представлений, когда вставки содержимого для окна были изменены, чтобы окно соответствующим образом корректировало его содержимое. Переопределяя этот метод, вы можете обрабатывать вставки (и, следовательно, ваш макет приложения), но вы хотите.

форма: https://developer.android.com/training/system-ui/status.html#behind

Ответ 18

Если вы точно знаете размер VS height

как

например, в устройстве с размером экрана 320 x 480, высота строки состояния составляет 25 пикселей, для устройства с разрешением 480 x 800 высота строки состояния должна быть 38 пикселей

то вы можете просто получить ширину вашего представления/размер экрана, вы можете просто использовать оператор if else, чтобы получить высоту строки состояния

Ответ 19

Причина, по которой главный ответ не работает для некоторых людей, заключается в том, что вы не можете получить размеры представления, пока он не будет готов к рендерингу. Используйте 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
        }
    }
}

Это самый надежный метод.

Ответ 20

Благодаря @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 С#, но это только его. Работает с надрезами и т.д.

Ответ 21

Xamarin

    if (Android.OS.Build.VERSION.SdkInt < BuildVersionCodes.M)
        StatusBarHeight = 25;
    else
        StatusBarHeight = 24;

Ответ 22

Этот вопрос недавно стал актуальным для меня из-за выемки в моем Pixel 3XL. Мне очень понравилось решение для разработчиков Android, но я хотел иметь возможность получить высоту строки состояния по своему желанию, так как это было особенно необходимо для полноэкранной анимации, которую мне нужно было воспроизвести. Функция ниже включила надежный запрос:

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

Вы, конечно, захотите передать слабую ссылку на действие на статический параметр метода класса Helper, но для краткости я воздержался в этом примере. blurBitmap и errorHudFrameLayout опущены по той же причине, поскольку они не имеют прямого отношения к получению высоты строки состояния.