Как я могу программно узнать размер экрана в единицах измерения, используемых для событий касания и измерения / макета просмотра? Другими словами, мне нужны координаты правого нижнего угла экрана в системе координат, используемой событиями касания '
getRawX()/getRawY()и View.getLocationOnScreen().
Я не решаюсь называть желаемые единицы события / просмотра «пикселями», поскольку, очевидно, в моем телефоне есть несколько понятий «пиксели» в различных режимах, и они не складываются в единый рассказ.
Я вижу, что об этом много спрашивали и на него много отвечали в stackoverflow и в других местах, но ни один из ответов на самом деле не работает на моем телефоне (droid 4, android 4.1.2) во всех режимах:
- Могу ли я программно узнать ширину экрана в приложении для Android?
- Как программно получить ScreenSize в Android
- Android устанавливает видимость программного обеспечения в зависимости от размера экрана
- Как узнать высоту экрана в Android?
- Получите высоту экрана в Android
- https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
- http://shuklaxyz.blogspot.com/2012/02/how-to-programmatically-figure-out.html
- http://coderock.net/how-to-determine-screen-resolution-programmatically/
- http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
- Android и установка ширины и высоты программно в дп
- http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatically-in-android/
- http://www.androidsnippets.com/get-size-and-orientation-of-the-screen
- http://grokbase.com/t/gg/android-developers/127aatfqb6/how-to-determine-screen-resolution-programmatically
(Вот это да!)
Это для кода библиотеки, который должен работать независимо от того, находится ли приложение в «режиме совместимости с экраном» (т.е. targetSdkVersion <= 10 в манифесте) или нет, и я также не хочу делать никаких предположений о положении, размере , или наличие строки состояния или любых других подобных украшений экрана.
Вот факты:
мой телефон (дроид 4 под управлением Android 4.1.2) имеет физические пиксели 540x960, то есть маленькие цветные светящиеся точки.
размер экрана в требуемых единицах измерения, исходя из событий касания и просмотра измерений, составляет 360x640, когда приложение находится в режиме совместимости с экраном, и 540x960, когда приложение не находится в режиме совместимости с экраном. Это числа, которые мне нужно найти программно, не прибегая к событиям касания или представлениям, чтобы найти их, но мне очень трудно найти какой-либо API, который вернет эти числа.
Все объекты Display и DisplayMetrics, полученные различными способами, заявляют, что размер экрана составляет 540x960 "пикселей" (независимо от того, находится ли он в режиме совместимости с экраном или нет). Если быть точным, все следующие элементы всегда говорят 540x960: DisplayMetrics. {Width, height} Pixels, Display.getSize (), Display.getRealSize (), Display.get {Width, Height} (),
Все объекты конфигурации, полученные различными способами, говорят screen {Width, Height} Dp = 360x614 (в режиме совместимости с экраном или нет). Я не верю, что это представляет собой весь экран, поскольку соотношение сторон неправильное. (Я думаю, что это весь экран за вычетом строки состояния; мне нужен весь экран.) Я думаю, можно с уверенностью сказать, что весь экран имеет разрешение 360x640 dp, хотя я не знаю ни одного API, возвращающего это 640.
DisplayMetrics, полученные различными способами, говорят, что "плотность" составляет 1,0f в режиме совместимости с экраном и 1,5f, когда не в режиме совместимости с экраном.
Действия
getWindow().getAttributes().{width,height}бесполезны, поскольку обычно содержат,MATCH_PARENTа не фактические размеры. Но я, по-видимому, могу получить желаемый ответ от действияgetWindow().getDecorView().getMeasured{Width,Height}()(что на самом деле удивительно, поскольку decorView окна действия не выглядит так, как будто он занимает весь экран; похоже, что он занимает экран без строки состояния). Но я не хочу полагаться на это, потому что, если когда-либо изменится размер окна (появится мягкая клавиатура? Кто-то вызывает window.setAttributes ()? Или, может быть, я вообще не в Activity), это явно будет все неправильно.
Я понимаю, что должна выполняться следующая формула: пиксели = dp * плотность Это похоже на все указанные числа ((3), (4), (5) выше), когда не в режиме совместимости с экраном: 540x960 = 360x640 * 1,5 А вот в режиме совместимости экранов не складывается: 540x960! = 360x640 * 1 Значит, что-то не так.
Я думаю, что самое простое объяснение состоит в том, что методы, перечисленные в пункте (3) выше, просто дают неправильный ответ для «пикселей» в режиме совместимости экрана - то есть они были предназначены для возврата «пикселей» в размере 360x640, но они ошибочны. вместо этого возвращается 540x960. Но могут быть другие взгляды на это.
В любом случае, получение желаемых чисел независимо от режима из приведенных выше частей головоломки, безусловно, является сложной задачей. Я нашел способ, который, кажется, работает на моем телефоне в обоих режимах, но он чрезвычайно окольный и основан на двух предположениях, которые все еще кажутся довольно шаткими (как описано в комментариях к коду ниже).
Вот мой рецепт:
/** get screen size in "pixels", i.e. touchevent/view units.
* on my droid 4, this is 360x640 or 540x960
* depending on whether the app is in screen compatibility mode
* (i.e. targetSdkVersion<=10 in the manifest) or not. */
public void getScreenSizePixels(int widthHeightInPixels[/*2*/])
{
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
// Note, screenHeightDp isn't reliable
// (it seems to be too small by the height of the status bar),
// but we assume screenWidthDp is reliable.
// Note also, dm.widthPixels,dm.heightPixels aren't reliably pixels
// (they get confused when in screen compatibility mode, it seems),
// but we assume their ratio is correct.
double screenWidthInPixels = (double)config.screenWidthDp * dm.density;
double screenHeightInPixels = screenWidthInPixels * dm.heightPixels / dm.widthPixels;
widthHeightInPixels[0] = (int)(screenWidthInPixels + .5);
widthHeightInPixels[1] = (int)(screenHeightInPixels + .5);
}
Есть ли лучший / более чистый способ узнать размер экрана?
DisplayMetricsникогда не обновляется такими изменениями. Есть такие вопросы , как это уже подали.