Получить размеры экрана в пикселях
Я создал некоторые пользовательские элементы, и я хочу программно поместить их в верхний правый угол (n
пикселей от верхнего края и m
пикселей от правого края). Поэтому мне нужно получить ширину экрана и высоту экрана, а затем установить положение:
int px = screenWidth - m;
int py = screenHeight - n;
Как мне получить screenWidth
и screenHeight
в основном мероприятии?
Ответы
Ответ 1
Если вы хотите размеры экрана в пикселях, вы можете использовать getSize
:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Если вы не в Activity
вы можете получить Display
по умолчанию через WINDOW_SERVICE
:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Если вы находитесь во фрагменте и хотите выполнить это, просто используйте Activity.WindowManager (в Xamarin.Android) или getActivity(). GetWindowManager() (в java).
Перед введением getSize
(на уровне API 13) вы могли использовать методы getWidth
и getHeight
, которые сейчас не рекомендуются:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
Однако для описываемого вами варианта использования поле/отступ в макете кажется более подходящим.
Другой способ: DisplayMetrics
Структура, описывающая общую информацию об отображении, такую как его размер, плотность и масштабирование шрифта. Чтобы получить доступ к членам DisplayMetrics, инициализируйте объект следующим образом:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Мы можем использовать widthPixels
чтобы получить информацию для:
"Абсолютная ширина дисплея в пикселях."
Пример:
Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Ответ 2
Одним из способов является:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Это устарело, и вместо этого вы должны попробовать следующий код. Первые две строки кода дают вам объекты DisplayMetrics
. Этот объект содержит поля, такие как heightPixels
, widthPixels
.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Ответ 3
Он может не отвечать на ваш вопрос, но было бы полезно знать (я сам искал его, когда пришел к этому вопросу), что если вам нужно измерение View, но ваш код выполняется, когда его макет не был (например, в onCreate()
) вы можете установить ViewTreeObserver.OnGlobalLayoutListener
с помощью View.getViewTreeObserver().addOnGlobalLayoutListener()
и поместить соответствующий код, для которого требуется измерение вида. Обратный вызов слушателя будет вызываться, когда макет будет выложен.
Ответ 4
(ответ 2012 года, может быть устаревшим). Если вы хотите поддержать pre Honeycomb, вам нужно будет установить обратную совместимость до API 13. Что-то вроде:
int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Point size = new Point();
w.getDefaultDisplay().getSize(size);
measuredWidth = size.x;
measuredHeight = size.y;
} else {
Display d = w.getDefaultDisplay();
measuredWidth = d.getWidth();
measuredHeight = d.getHeight();
}
Конечно, устаревшие методы в конечном итоге будут выведены из самых последних SDK, но пока мы по-прежнему полагаемся на большинство наших пользователей, имеющих Android 2.1, 2.2 и 2.3, это то, с чем мы остались.
Ответ 5
Я пробовал все возможные "решения" безуспешно, и я заметил, что приложение "Dalvik Explorer" Elliott Hughes всегда показывает правильное измерение на любой версии Android/OS. В итоге я посмотрел его проект с открытым исходным кодом, который можно найти здесь: https://code.google.com/p/enh/
Здесь весь соответствующий код:
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
// used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
// used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
EDIT: немного улучшенная версия (избегайте исключений об обстреле в версии, не поддерживаемой ОС):
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
Ответ 6
Для доступа к высоте строки состояния для устройств Android мы предпочитаем программный способ ее получения:
Пример кода
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = getResources().getDimensionPixelSize(resId);
}
Переменная result
дает высоту в пикселе.
Для быстрого доступа
Для получения дополнительной информации о высоте Title bar
, Navigation bar
и Content View
, любезно посмотрите на Размеры экрана устройства Android.
Ответ 7
Простейший способ:
int screenHeight = getResources().getDisplayMetrics().heightPixels;
int screenWidth = getResources().getDisplayMetrics().widthPixels;
Ответ 8
Сначала получите представление (например, findViewById()
), а затем вы можете использовать getWidth() на просмотра самого себя.
Ответ 9
У меня есть две функции: одна для отправки контекста, а другая высота и ширина в пикселях:
public static int getWidth(Context mContext){
int width=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
width = size.x;
}
else{
width = display.getWidth(); // Deprecated
}
return width;
}
и
public static int getHeight(Context mContext){
int height=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
height = size.y;
}
else{
height = display.getHeight(); // Deprecated
}
return height;
}
Ответ 10
Для динамического масштабирования с использованием XML существует атрибут "android: layout_weight"
В приведенном ниже примере, измененном от синхронного ответа на этот поток, отображается кнопка, которая занимает 75% экрана (вес =.25) и текстовое представление заняв оставшиеся 25% экрана (вес =.75).
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text="somebutton">
<TextView android:layout_width="fill_parent"
android:layout_height="Wrap_content"
android:layout_weight=".75">
</LinearLayout>
Ответ 11
Это код, который я использую для задачи:
// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
display.getSize(screen);
} else {
screen.x = display.getWidth();
screen.y = display.getHeight();
}
Кажется достаточно чистым и, тем не менее, заботится об устаревании.
Ответ 12
Разве это не лучшее решение? DisplayMetrics поставляется со всем необходимым и работает с API 1.
public void getScreenInfo(){
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
heightPixels = metrics.heightPixels;
widthPixels = metrics.widthPixels;
density = metrics.density;
densityDpi = metrics.densityDpi;
}
Вы также можете получить фактический дисплей (включая декодеры экрана, такие как строка состояния или панель навигации программного обеспечения) с помощью getRealMetrics, но это работает только с 17+.
Я что-то пропустил?
Ответ 13
Просто добавив к Франческо ответ. Другой наблюдатель, более подходящий, если вы хотите узнать местоположение в окне или местоположении на экране,
ViewTreeObserver.OnPreDrawListener()
Это также можно использовать для поиска других атрибутов представления, которое в большинстве случаев неизвестно в onCreate(), например. прокрученное положение, масштабированное положение.
Ответ 14
Найдите ширину и высоту экрана:
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
Используя это, мы можем получить последний и выше SDK 13.
// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
Point size = new Point();
display.getSize(size);
width = size.x;
Log.i("width", "if =>" +width);
}
else {
width = display.getWidth();
Log.i("width", "else =>" +width);
}
Ответ 15
Используя следующий код в Activity.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Ответ 16
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Ответ 17
Я нашел, что это сделало трюк.
Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Ответ 18
public class AndroidScreenActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
String str_ScreenSize = "The Android Screen is: "
+ dm.widthPixels
+ " x "
+ dm.heightPixels;
TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
mScreenSize.setText(str_ScreenSize);
}
}
Ответ 19
Нужно сказать, что если вы не находитесь в Activity
, но в View
(или имеете переменную типа View
в своей области), нет необходимости использовать WINDOW_SERVICE
. Затем вы можете использовать как минимум два способа.
Во-первых:
DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();
Во-вторых:
DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);
Все эти методы, которые мы называем здесь, не устарели.
Ответ 20
Для получения размеров экрана используйте отображаемые метрики
DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null)
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display defaultDisplay = windowManager.getDefaultDisplay();
defaultDisplay.getRealMetrics(displayMetrics);
}
Получить высоту и ширину в пикселях
int width =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Ответ 21
Это не ответ для OP, так как он хотел отображать размеры в реальных пикселях. Мне нужны размеры в "device-independent-pixels" и собраны ответы отсюда fooobar.com/questions/2415/... и здесь fooobar.com/questions/2416/... Я придумал это:
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
Ответ 22
Существует не устаревший способ сделать это с помощью DisplayMetrics (API 1), что позволяет избежать беспорядка try/catch:
// initialize the DisplayMetrics object
DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();
// populate the DisplayMetrics object with the display characteristics
getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);
// get the width and height
screenWidth = deviceDisplayMetrics.widthPixels;
screenHeight = deviceDisplayMetrics.heightPixels;
Ответ 23
Я бы обернул код getSize следующим образом:
@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
Point size = new Point();
Display d = a.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
d.getSize(size);
} else {
size.x = d.getWidth();
size.y = d.getHeight();
}
return size;
}
Ответ 24
Вы можете получить размер высота, используя:
getResources().getDisplayMetrics().heightPixels;
и размер ширина, используя
getResources().getDisplayMetrics().widthPixels;
Ответ 25
Сначала загрузите файл XML, а затем напишите этот код:
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());
Покажите ширину и высоту в соответствии с разрешением экрана.
Ответ 26
Для тех, кто ищет размер экрана без использования Строка состояния и Панель действий (также благодаря ответу Swapnil):
DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
screen_h -= getResources().getDimensionPixelSize(resId);
}
TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Ответ 27
Следуйте приведенным ниже методам:
public static int getWidthScreen(Context context) {
return getDisplayMetrics(context).widthPixels;
}
public static int getHeightScreen(Context context) {
return getDisplayMetrics(context).heightPixels;
}
private static DisplayMetrics getDisplayMetrics(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics;
}
Ответ 28
Бывают случаи, когда вам нужно знать точные размеры доступного пространства для макета, когда в действии onCreate.
Подумав, я решил это сделать.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivityForResult(new Intent(this, Measure.class), 1);
// Return without setting the layout, that will be done in onActivityResult.
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -1);
// Width is now set to the precise available width, and a layout can now be created. ...
}
}
public final class Measure extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
Measure.this.setResult(Activity.RESULT_OK, data);
// Tell this activity to finish, so the result is passed back.
Measure.this.finish();
}
}
}
Если по какой-то причине вы не хотите добавлять другую активность в манифест Android, вы можете сделать это следующим образом:
public class MainActivity extends Activity {
static Activity measuringActivity;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras == null) {
extras = new Bundle();
}
int width = extras.getInt("Width", -2);
if (width == -2) {
// First time in, just start another copy of this activity.
extras.putInt("Width", -1);
startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
// Return without setting the layout, that will be done in onActivityResult.
return;
}
if (width == -1) {
// Second time in, here is where the measurement takes place.
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -3);
// Width is now set to the precise available width, and a layout can now be created.
...
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
// Tell the (second) activity to finish.
MainActivity.measuringActivity.finish();
}
}
Ответ 29
Если вы не хотите накладных расходов на WindowManagers, Points или Displays, вы можете захватить атрибуты высоты и ширины самого верхнего элемента View в вашем XML, при условии, что его высота и ширина установлены на match_parent. (Это верно, если ваш макет занимает весь экран.)
Например, если ваш XML начинается с чего-то вроде этого:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/entireLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
Затем findViewById(R.id.entireLayout).getWidth()
вернет ширину экрана, а findViewById(R.id.entireLayout).getHeight()
вернет высоту экрана.
Ответ 30
У меня есть активность заставки с LinearLayout как корневое представление, которое имеет match_parent для его ширины и высоты. Это код в методе onCreate()
этого действия. Я использую эти меры во всех других действиях приложения.
int displayWidth = getRawDisplayWidthPreHoneycomb();
int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
pf.setScreenParameters(displayWidth, usableDisplayHeight);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return;
}
int displayWidth = Math.min(right, bottom);
int usableDisplayHeight = Math.max(right, bottom);
pf.setScreenParameters(displayWidth, usableDisplayHeight);
}
});
}
Ниже перечислены реализации описанных выше методов:
private int getRawDisplayWidthPreHoneycomb() {
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
int widthPixels = displayMetrics.widthPixels;
int heightPixels = displayMetrics.heightPixels;
return Math.min(widthPixels, heightPixels);
}
private int getRawDisplayHeightPreHoneycomb() {
WindowManager w = getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
return Math.max(widthPixels, heightPixels);
}
public int getStatusBarHeight() {
int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
Это приводит к росту и ширине используемого дисплея, исключая любые типы баров (строка состояния, панель навигации) для всех версий API и различных типов устройств (телефонов и планшетов).