Я создал некоторые пользовательские элементы, и я хочу программно поместить их в верхний правый угол (n
пикселей от верхнего края и m
пикселей от правого края). Поэтому мне нужно получить ширину экрана и высоту экрана, а затем установить положение:
int px = screenWidth - m;
int py = screenHeight - n;
Как мне получить screenWidth
и screenHeight
в основном мероприятии?
Если вы хотите отображать размеры в пикселях, вы можете использовать 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();
До введения getSize
(в уровне API 13) вы могли бы использовать методы getWidth
и getHeight
, которые теперь устарели:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
В случае использования, которое вы описываете, маржа/заполнение в макете представляется более подходящим.
22 октября 2015 года
Другие способы: DisplayMetrics
Структура, описывающая общую информацию о дисплее, такую как размер, плотность и масштабирование шрифтов. Чтобы получить доступ к элементам DisplayMetrics, выполните инициализацию объекта следующим образом:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Мы можем использовать widthPixels
для получения информации для:
"Абсолютная ширина отображения в пикселях."
Пример:
Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Один из способов:
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;
Он может не отвечать на ваш вопрос, но было бы полезно знать (я сам искал его, когда пришел к этому вопросу), что если вам нужно измерение View, но ваш код выполняется, когда его макет не был (например, в onCreate()
) вы можете установить ViewTreeObserver.OnGlobalLayoutListener
с помощью View.getViewTreeObserver().addOnGlobalLayoutListener()
и поместить соответствующий код, для которого требуется измерение вида. Обратный вызов слушателя будет вызываться, когда макет будет выложен.
(ответ 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, это то, с чем мы остались.
Я пробовал все возможные "решения" безуспешно, и я заметил, что приложение "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) {
}
Для доступа к высоте строки состояния для устройств 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.
getResources().getDisplayMetrics().heightPixels + result
дает фактическую полноэкранную высоту. Ответ Драгана Марьяновича также работает, но я предпочитаю это более короткое и простое решение.
OnApplyWindowInsetsListener
.
Простейший способ:
int screenHeight = getResources().getDisplayMetrics().heightPixels;
int screenWidth = getResources().getDisplayMetrics().widthPixels;
Сначала получите представление (например, findViewById()
), а затем вы можете использовать getWidth() на просмотра самого себя.
У меня есть две функции: одна для отправки контекста, а другая высота и ширина в пикселях:
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;
}
@SuppressLint("NewApi")
чуть выше сигнатуры функции, чтобы иметь возможность компилировать.
Разве это не лучшее решение? 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+.
Я что-то пропустил?
Это код, который я использую для задачи:
// `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();
}
Кажется достаточно чистым и, тем не менее, заботится об устаревании.
Для динамического масштабирования с использованием 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>
Найдите ширину и высоту экрана:
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);
}
Просто добавив к Франческо ответ. Другой наблюдатель, более подходящий, если вы хотите узнать местоположение в окне или местоположении на экране, ViewTreeObserver.OnPreDrawListener()
Это также можно использовать для поиска других атрибутов представления, которое в большинстве случаев неизвестно в onCreate(), например. прокрученное положение, масштабированное положение.
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Используя следующий код в Activity.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Нужно сказать, что если вы не находитесь в Activity
, но в View
(или имеете переменную типа View
в своей области), нет необходимости использовать WINDOW_SERVICE
. Затем вы можете использовать как минимум два способа.
Во-первых:
DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();
Во-вторых:
DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);
Все эти методы, которые мы называем здесь, не устарели.
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);
}
}
Я нашел, что это сделало трюк.
Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Это не ответ для OP, так как он хотел отображать размеры в реальных пикселях. Мне нужны размеры в "device-independent-pixels" и собраны ответы отсюда https://stackoverflow.com/questions/4605527/converting-pixels-to-dp и здесь https://stackoverflow.com/questions/6656540/android-convert-px-to-dp-video-aspect-ratio Я придумал это:
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
Я бы обернул код 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;
}
Существует не устаревший способ сделать это с помощью 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;
Следуйте приведенным ниже методам:
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;
}
Сначала загрузите файл XML, а затем напишите этот код:
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());
Покажите ширину и высоту в соответствии с разрешением экрана.
Для тех, кто ищет размер экрана без использования Строка состояния и Панель действий (также благодаря ответу 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);
}
Если вы не хотите накладных расходов на 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()
вернет высоту экрана.
Бывают случаи, когда вам нужно знать точные размеры доступного пространства для макета, когда в действии 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();
}
}
Для получения размеров экрана используйте отображаемые метрики
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;
У меня есть активность заставки с 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 и различных типов устройств (телефонов и планшетов).
Вы можете получить размер высота, используя:
getResources().getDisplayMetrics().heightPixels;
и размер ширина, используя
getResources().getDisplayMetrics().widthPixels;
Выше ответ не будет работать, если класс Display не будет работать, вы можете получить ширину и высоту ниже.
private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;
public static int[] getScreenSize(Context context) {
int[] widthHeight = new int[2];
widthHeight[WIDTH_INDEX] = 0;
widthHeight[HEIGHT_INDEX] = 0;
try {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthHeight[WIDTH_INDEX] = size.x;
widthHeight[HEIGHT_INDEX] = size.y;
if (!isScreenSizeRetrieved(widthHeight))
{
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
widthHeight[0] = metrics.widthPixels;
widthHeight[1] = metrics.heightPixels;
}
// Last defense. Use deprecated API that was introduced in lower than API 13
if (!isScreenSizeRetrieved(widthHeight)) {
widthHeight[0] = display.getWidth(); // deprecated
widthHeight[1] = display.getHeight(); // deprecated
}
} catch (Exception e) {
e.printStackTrace();
}
return widthHeight;
}
private static boolean isScreenSizeRetrieved(int[] widthHeight) {
return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
}
Простая функция, совместимая с более низкими версиями.
/**
* @return screen size int[width, height]
*
* */
public int[] getScreenSize(){
Point size = new Point();
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
w.getDefaultDisplay().getSize(size);
return new int[]{size.x, size.y};
}else{
Display d = w.getDefaultDisplay();
//noinspection deprecation
return new int[]{d.getWidth(), d.getHeight()};
}
}
Использовать:
int width = getScreenSize()[0];
int height = getScreenSize()[1];
Вот простая адаптация из некоторых ответов выше в реализации Kotlin. Он требует, как указано выше, windowsSoftInput = "adjustResize" в манифесте:
class KeyboardWatcher(private val layoutRooView: View) {
companion object {
private const val MIN_KEYBOARD_HEIGHT = 200f
}
private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetrics
private var stateVisible = false
var observer: ((Boolean) -> Unit)? = null
init {
layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {
val heightDiff = layoutRooView.rootView.height - layoutRooView.height
if (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {
stateVisible = true
observer?.invoke(stateVisible)
} else if(stateVisible) {
stateVisible = false
observer?.invoke(stateVisible)
}
}
}
private fun dpToPx(valueInDp: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
}
}
И использовать:
val activityRootView = findViewById<ViewGroup>(R.id.activityRoot)
KeyboardWatcher(activityRootView).observer = { visible ->
if (visible) do something here ...
}
Эта функция возвращает приблизительный размер экрана в дюймах.
public double getScreenSize()
{
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
int dens=dm.densityDpi;
double wi=(double)width/(double)dens;
double hi=(double)height/(double)dens;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);
return screenInches;
}
DisplayMetrics dm = getResources().getDisplayMetrics();
float fwidth = dm.density * dm.widthPixels;
float fheight = dm.density * dm.heightPixels;
Если getSize
получает сообщение об ошибке из-за вашей minSDKVersion, и вы не хотите использовать устаревшие методы (getWidth
и getHeight
), решение getMetrics
было первоначально опубликовано в 2011 году компанией Balaji.K... И Ник добавил комментарий, объясняющий getDisplayMetrics
также рассматривает размер строки состояния.
Некоторые другие комментарии относятся к умножению на масштаб (плотность), чтобы получить точное значение поплавка размеров. Протестировано в Android v2.2 (API 8) и v4.0 с хорошими результатами и нет ошибок/предупреждений.