Высота строки состояния?
есть ли способ получить высоту строки состояния + заголовок? Проверка форума dev показывает тот же вопрос, но нет решения (которое я мог бы найти).
Я знаю, что мы можем получить его после начального прохода макета, но я хочу получить его в onCreate() моей деятельности.
спасибо
10 ответов:
Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; Log.i("*** Jorgesys :: ", "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; }
хотя это старый вопрос, я обнаружил, что ответ не работал в
onCreate()
:Я нашел этот код здесь, который работает в
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; }
Я надеюсь, что это поможет всем, кто сталкивается с этой проблемой.
для тех, кто, как и я, хочет использовать его в своих XML-макетах:
<... android:layout_marginTop="@*android:dimen/status_bar_height" ... />
Не смущайтесь тем, что Android Studio (2.2 Preview 3 -- на момент написания статьи) не поддерживает это понятие. Время выполнения делает. Я взял его из исходного кода Google.
Я бы предложил следующий код:
Rect rect = new Rect(); Window window = activity.getWindow(); if (window != null) { window.getDecorView().getWindowVisibleDisplayFrame(rect); android.view.View v = window.findViewById(Window.ID_ANDROID_CONTENT); android.view.Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); //return result title bar height return display.getHeight() - v.getBottom() + rect.top; }
два примера:
1) Устройство 1 бренд: samsung, устройство: Магуро, доска: тунец, cpu_abi: armeabi-v7a, дисплей: ICL53F. M420KREL08, производитель: samsung, модель: Galaxy Nexus, версия.релиз: 4.0.2, версия.sdk: 14;
разрешение экрана: 1280 x 720.На этом устройстве нет аппаратных кнопок.
результаты:
rect: left=0 right=720 top=72 bottom=1208; v: left=0 right=720 top=72 bottom=1208; display: height=1208 width=720; correct result=72;
устройство 1 имеет строку заголовка в верхней части экрана и строку состояния с программные кнопки в нижней части экрана.
2) Устройство 2 устройство: Браво, доска: Браво, cpu_abi: armeabi-v7a, дисплей: FRG83G, производитель: HTC, модель: HTC Desire, версия.релиз: 2.2.2, версия.sdk: 8,
разрешение экрана: 800 x 400. Это устройство имеет аппаратные кнопки.
результаты:
rect: left=0 right=480 top=38 bottom=800; v: left=0 right=480 top=0 bottom=800; display: height=800 width=480; correct result: phone_bar_height=38;
устройство 2 имеет строку заголовка в верхней части экрана и не имеет строки состояния вообще.
было предложено два решения выше:
A) v.getTop() - rect.top
(это неверно для устройства 1 - это дает 0 вместо 72)
B) display.getHeight() - v.getHeight()
(это неверно для устройства 2 - это дает 0 вместо 38)
вариант:
display.getHeight() - v.getBottom() + rect.top
дает правильные результаты в обоих случаях.
обновление
3) Еще один пример (третье устройство): бренд: LGE, устройство: v909, cpu_abi: armeabi-v7a, дисплей: HMJ37, модель: LG-V909, версия.освобождать: 3.1, версия.sdk: 12
rect: left=0 right=1280 top=0 bottom=720 v: left=0 right=1280 top=0 bottom=720 Display: height=768 width=1280 phone_bar_height=48
устройство 3 имеет горизонтальную ориентацию, не имеет строки заголовка в верхней части экрана и имеет строку состояния в нижней части экрана.
так вот:
int size_of_title_bar = rect.top; int size_of_status_bar = display.getHeight() - v.getBottom();
это правильно для устройств 2 и 3. Я не уверен в устройстве 1. Пользователь прислал мне скриншот устройства 1. Там есть строка состояния с программной кнопкой. Но выражение "дисплей.getHeight () - v. getBottom ()" дает 0.
прикрепите runnable к одному из ваших представлений в методе onCreate и поместите туда приведенный выше код. Это приведет к тому, что приложение будет вычислять высоту строки состояния + titlescreen, когда они будут прикреплены к экрану.
взгляните на код ниже:
myView.post(new Runnable() { @Override public void run() { Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; } });
Если это все еще не делает трюк, попробуйте вызвать метод postDelayed представления вместо post и добавить значение миллисекунды в качестве второго аргумента.
поддерживаемый способ получения высоты строки состояния-использовать
WindowInsets
класс, начиная с API 21+:customView.setOnApplyWindowInsetsListener((view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); });
или
WindowInsetsCompat
для библиотек поддержки:ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); });
вы также можете переопределить
onApplyWindowInsets
метод внутри вид:public class CustomView extends View { @Override public WindowInsets onApplyWindowInsets(final WindowInsets insets) { final int statusBarHeight = insets.getStableInsetTop(); return insets.consumeStableInsets(); } }
для более подробной информации я бы рекомендовал проверить Chris Banes talk - стать монтажником главного окна (слайды доступен здесь).
вы также можете взять размер строки состояния, найденной в dimens.xml-файл android, используя путь, что этот блог описывает.
Это может сделать высоту строки состояния без необходимости ждать розыгрыш.
цитируя код из сообщения в блоге:
public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
вам нужно поместить этот метод в класс ContextWrapper.
Я думаю, что лучший способ рассчитать это, чтобы получить высоту полноэкранного минус наш основной макет
phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight() - mainView.getHeight();
и вы можете положить его в
onGlobalLayout()
. Это работает на планшетах тоже, я попробовал его на тему.NoTitleBar, но он должен всегда работает.может быть, вы даже можете улучшить его и использовать его в
onCreate()
изменениеmainView.getHeight()
доmainView.getMeasuredHeight()
.
решение, опубликованное Jorgesys, очень хорошее, но оно не работает внутри метода onCreate (). Я думаю, это потому, что строка состояния и заголовок создаются после onCreate().
решение простое - вы должны поместить код внутри runnable и выполнить его после onCreate () с помощью
root.post((Runnable action) );
Так что все решение:
root = (ViewGroup)findViewById(R.id.root); root.post(new Runnable() { public void run(){ Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; Log.i("*** jakkubu :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight); } });
мне здесь
по состоянию на API 23 есть лучшее решение для получения высоты строки состояния. API 23 добавляет a
WindowInsets
функция, так что вы можете использовать этот код, чтобы получить размер системных вставок, в данном случае в верхней части.public int getStatusBarHeight() { if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { return binding.mainContent.getRootWindowInsets().getStableInsetTop(); } int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if(resourceId != 0) { return getResources().getDimensionPixelSize(resourceId); } return 0; }
отметим, что
getRootWindowInsets()
вернет null до тех пор, пока представление не будет прикреплено к окну, поэтому его нельзя использовать непосредственно вonCreate()
но вы можете добавить прослушиватель для прикрепления окна и сделать это там-здесь я добавляю вставку строки состояния в размер моей панели инструментов, которую я скрыть и показать, вместе со строкой состояния. Когда он отображается, мне нужна строка состояния поверх нее, поэтому я добавляю высоту строки состояния в верхнюю панель инструментов.binding.mainContent.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View view) { binding.toolbar.setPadding(binding.toolbar.getPaddingLeft(), binding.toolbar.getPaddingTop() + getStatusBarHeight(), binding.toolbar.getPaddingRight(), binding.toolbar.getPaddingBottom()); binding.mainContent.removeOnAttachStateChangeListener(this); } @Override public void onViewDetachedFromWindow(View view) { } });