Як я можу програмно визначити розмір екрана в одиницях, використовуваних сенсорними подіями та Переглядати вимірювання / макет? Іншими словами, я хочу, щоб координати нижнього правого кута екрану в системі координат використовувались сенсорні події '
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-programmatic-figure-out.html
- http://coderock.net/how-to-determine-screen-resolution-programmatic/
- http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
- Android та налаштування ширини та висоти програмно в одиницях dp
- http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatic-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-programmatic
(Ого!)
Це для коду бібліотеки, який повинен працювати незалежно від того, перебуває програма в "режимі сумісності екрана" (тобто targetSdkVersion <= 10 в маніфесті) чи ні, і я також не хочу робити жодних припущень щодо позиції, розміру або наявність рядка стану чи будь-яких інших подібних прикрас екрана.
Ось факти:
мій телефон (дроїд 4 під керуванням Android 4.1.2) має 540x960 фізичних пікселів, тобто маленькі кольорові світяться точки.
розмір екрана в потрібних одиницях - від перегляду подій на дотик та перегляду вимірювань - 360x640, коли додаток перебуває в режимі екранного компата, 540x960, коли програма не перебуває в режимі екранного компата. Це номери, які мені потрібно знайти програмно, не зв'язуючись із подіями дотику чи Переглядами, щоб знайти їх, але у мене виникають великі труднощі з пошуком будь-якого API, який поверне ці числа.
Об'єкти Display і DisplayMetrics, отримані різними способами, стверджують, що розмір екрана становить 540x960 "пікселів" (чи в режимі компактного екрану, чи ні). Щоб конкретизувати, весь час говорять про 540x960: DisplayMetrics. {Width, height} Пікселі, Display.getSize (), Display.getRealSize (), Display.get {Width, Height} (),
Об'єкти конфігурації, отримані різними способами, всі говорять про екран {Width, Height} Dp = 360x614 (незалежно від того, чи є він у режимі екрана чи ні). Я не вірю, що це представляє весь екран, оскільки співвідношення сторін неправильне. (Я думаю, що це весь екран мінус статус стану; мені потрібен весь екран.) Я думаю, що можна впевнено сказати, що весь екран 360x640 dp, хоча я не знаю жодного API, який повертає цей 640.
DisplayMetrics, отримані різними способами, кажуть, що "щільність" становить 1,0f, коли в режимі екранного компата, 1,5f, коли не в режимі екранного компат.
Діяльність
getWindow().getAttributes().{width,height}не корисна, оскільки зазвичай містить,MATCH_PARENTа не фактичні розміри. Але я можу отримати бажану відповідь від діяльностіgetWindow().getDecorView().getMeasured{Width,Height}()(що насправді дивно, оскільки декорView вікна діяльності не виглядає так, що він займає весь екран; схоже, що він займає екран за мінусом рядка стану). Але я не хочу на це покладатися, тому що якщо вікно коли-небудь буде змінено (з'являється м'яка клавіатура? Хтось викликає window.setAttributes ()? Або, можливо, я взагалі не перебуваю в активності), це, очевидно, буде все неправильно.
Я розумію, що повинна міститись наступна формула: пікселі = 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ніколи не оновлюється такими змінами. Є такі питання , як це вже подали.