我不确定所需事件/视图单位是否为“像素”, 因为显然在手机上有几种“像素”概念, 它们没有形成一致的故事。
我在stackoverflow和其他地方看到这个问题被提出和回答了很多次, 但是没有一个答案在我的手机(Droid 4、Android 4.1.2)的所有模式下都有效。
- 如何在Android应用中以编程的方式找到屏幕宽度?
- 如何在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中以dp单位编程方式设置宽度和高度
- 如何在Android中以编程的方式获取屏幕尺寸
- 获取屏幕大小和方向的Android片段
- 如何在Android应用中以编程的方式确定屏幕分辨率
(哇!)
这是用于库代码的,需要在应用程序处于“屏幕兼容模式”(即目标SDK版本<=10在清单中)或不处于该模式时正常工作, 我也不想对状态栏或任何类似的屏幕装饰的位置、大小或存在做出任何假设。
以下是事实:
我的手机 (运行 Android 4.1.2 的 droid 4) 物理像素为 540x960, 即小彩色发光点。
从触摸事件和 View 测量来看,所需单位下的屏幕大小为 当应用程序处于屏幕兼容模式时为 360x640, 当应用程序不处于屏幕兼容模式时为 540x960。 这些是我需要以编程方式找到的数字, 而不必通过处理触摸事件或查找视图来找到它们, 但我非常难以找到任何API会返回这些数字。
以各种方式获取的 Display 和 DisplayMetrics 对象都声称屏幕大小为 540x960“像素” (无论是否处于屏幕兼容模式)。 具体来说,以下所有内容始终显示 540x960: DisplayMetrics.{width,height}Pixels、 Display.getSize()、 Display.getRealSize()、 Display.get{Width,Height}()
以各种方式获取的 Configuration 对象都说屏幕{Width,Height}Dp = 360x614 (无论是否处于屏幕兼容模式)。 我不认为这代表整个屏幕,因为宽高比是错误的。 (我认为这是整个屏幕减去状态栏; 我需要整个屏幕。) 我认为可以肯定地说整个屏幕是 360x640 dp, 尽管我不知道任何API返回那个 640。
以各种方式获取的 DisplayMetrics 声明“密度”是 在屏幕兼容模式下为 1.0f, 不在屏幕兼容模式下为 1.5f。
活动的
getWindow().getAttributes().{width,height}
并没有帮助,因为它通常包含MATCH_PARENT
而不是实际大小。 但是我显然可以从活动的以下位置获得所需的答案getWindow().getDecorView().getMeasured{Width,Height}()
(这实际上令人惊讶, 因为活动窗口的装饰视图看起来不像占据整个屏幕; 它看起来像是占据除状态栏之外的屏幕)。 但是我不想依赖这个,因为如果窗口被调整大小 (软键盘出现? 有人调用 window.setAttributes()? 或者我根本就不在一个 Activity 中), 这显然会完全错误。
我认为最简单的解释是, 上述 (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
从未更新此类更改。已经有像这样的问题被提出。 - S.D.