Получить высоту экрана в Android
Как получить доступную высоту экрана в Android? Мне нужна высота за вычетом строки состояния или строки меню или любых других украшений, которые могут быть на экране, и мне нужно, чтобы она работала на всех устройствах. Кроме того, мне нужно знать это в функции onCreate. Я знаю, что этот вопрос задавали раньше, но я уже пробовал их решения, и никто из них не работает. Вот некоторые из вещей, которые я пробовал:
Я тестировал этот код на API 7-17. К сожалению, на API 13 есть дополнительное пространство внизу как по горизонтали, так и по вертикали, а на API 10, 8 и 7 недостаточно места внизу как по горизонтали, так и по вертикали, (Я не тестировал устаревшие API):
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
TypedValue tv = new TypedValue();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
screenHeight -= TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
screenHeight -= getResources().getDimensionPixelSize(resourceId);
Это не учитывает строку состояния/строку меню:
Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
Также это:
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
screenHeight = size.y;
И это:
Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
screenWidth = size.x;
screenHeight = size.y;
Это не работает:
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
// since SDK_INT = 1;
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
try
{
// used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
screenWidth = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
}
catch (Exception ignored)
{
// Do nothing
}
try
{
// used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
screenWidth = realSize.x;
screenHeight = realSize.y;
}
catch (Exception ignored)
{
// Do nothing
}
Затем я использовал следующий код, чтобы вычесть высоту строки состояния и строки меню с высоты экрана:
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;
result = 0;
if (screenHeight >= screenWidth)
resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
else
resourceId = getResources().getIdentifier("navigation_bar_height_landscape", "dimen", "android");
if (resourceId > 0)
result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;
В API 17 он правильно вычисляет высоту строки состояния и строки меню в портрете, но не в ландшафте. В API 10 он возвращает 0. Мне нужно, чтобы он идеально работал на всех устройствах или минимальном API 7. Любая помощь была бы с благодарностью.
Ответы
Ответ 1
Рабочее решение:
Создайте два фиктивных представления:
<View
android:id="@+id/top"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_alignParentTop="true" />
<View
android:id="@+id/bottom"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_alignParentBottom="true" />
Теперь вы должны вызвать getLocationOnScreen(int [])
на этих двух представлениях, чтобы получить их местоположение. Эта функция возвращает массив из 2 целых чисел. Первый - это x и второй y. Нам требуется только y. Также обратите внимание, что правильные значения возвращаются только ПОСЛЕ создания всех представлений и завершается метод onCreate
.
Я тестировал этот код на регулярном фрагменте, вызванном из viewpager.
Код был в методе onCreateView
моего фрагмента. Мне все равно пришлось использовать postDelayed
для получения правильных значений.
final View top = (View) view.findViewById(R.id.top);
final View bottom = (View) view.findViewById(R.id.bottom);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
int topLoc[] = new int[2];
top.getLocationOnScreen(topLoc);
int BottomLoc[] = new int[2];
bottom.getLocationOnScreen(BottomLoc);
Log.d(Constants.debug, "topY: "+ topLoc[1]+" BottomY:" + BottomLoc[1]);
}
},4000);
У меня есть Nexus 4.
В обычном режиме (строка состояния и отображаемые программные кнопки):
07-05 02:28:23.367 565-565/com.torcellite.xx D/xx: topY: 50 BottomY:1182
В полноэкранном режиме (не отображается строка состояния или программные кнопки):
07-05 02:29:17.360 707-707/com.torcellite.xx D/xx: topY: 0 BottomY:1280
Все, что вам нужно сделать, это вычесть.
Надеюсь, что это поможет. Приветствия.
Ответ 2
Если вам нужны размеры экрана в пикселях, вы можете использовать getSize:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Если вы не находитесь в Activity
, вы можете получить Дисплей по умолчанию через WINDOW_SERVICE
:
WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
display.getSize(size);
int width = size.x;
int height = size.y;
До введения getSize
(в уровне API 13) вы могли бы использовать методы getWidth и getHeight, которые теперь устарели:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
Реферат: Получить размеры экрана в пикселях
Ответ 3
Для отображения
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
Для строки состояния
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Ответ 4
Я не пробовал использовать другой API, но я использую эти значения, чтобы выяснить, включена ли экранная клавиатура. Возможно, вы можете попробовать это и что-то сравнимое по ширине, чтобы получить то, что вам нужно?
Rect r = new Rect();
view.getWindowVisibleDisplayFrame(r);
int
screenHeight = view.getRootView().getHeight(), // height of the entire screen
appHeight = r.bottom - r.top, // height of the entire app
statusBarHeight = r.top, // height of the statusbar
pageHeight = view.getHeight(), // height of the app without title
appTitleHeight = appHeight - pageHeight, // height of the only the app title
topHeight = statusBarHeight + appTitleHeight;
Ответ 5
final View view = findViewById(R.id.root);
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// calculate the height in here...
ViewTreeObserver vto = view.getViewTreeObserver();
vto.removeGlobalOnLayoutListener(this);
}
});
Используйте этот прослушиватель внутри onCreate
(доступно с api 1). Вам нужно будет присвоить id @+id/root
родительскому элементу в xml-макете. Невозможно, чтобы размер возвращал результат 0, так как этот прослушиватель выполняет обратный вызов всякий раз, когда макеты расположены в поле зрения.
Ответ 6
Display currentDisplay = getWindowManager().getDefaultDisplay();
float dw = currentDisplay.getWidth();
float dh = currentDisplay.getHeight();
dh
даст вам высоту экрана.
Ответ 7
Как создать подклассу View как корень Activity. Сделайте этот вид заполняющим экран (он не пройдет мимо строки состояния) и переопределит onSizeChanged(). Сохраните эти значения и напишите для них геттер.
Ответ 8
Он может не отвечать на ваш вопрос, но может быть полезно знать (я был ища его сам, когда я пришел к этому вопросу), что если вам понадобится Просмотрите размер, но ваш код выполняется, когда его макет еще не выложены (например, в onCreate()) вы можете настроить ViewTreeObserver.OnGlobalLayoutListener с View.getViewTreeObserver(). AddOnGlobalLayoutListener() и поставьте соответствующий код, для которого требуется измерение вида. Слушатель обратный вызов будет вызываться, когда макет будет выложен.
любезность - Франческо Фелтринелли
Вы можете попробовать сделать это.
Ответ 9
Получить высоту корневого макета, загружаемого активностью. Если он не заполняет экран, поместите его в другой макет с свойством height fill_parent.