如何通过编程查找屏幕大小,
触摸事件所使用的单位
查看测量/布局?
换句话说,我要坐标
在屏幕的右下角,
在触摸事件使用的坐标系中
getRawX()/getRawY()
和 View.getLocationOnScreen()
。
我在犹豫是否将所需的事件/视图单元称为“像素” 因为显然有几个“像素”的概念 在我的手机上用各种模式, 他们的说法并不一致。
我知道这个问题已经得到了很多回答 堆栈溢出和其他地方, 但是 没有的答案在我的手机上是有效的 (droid4,android 4.1.2)所有模式:
(哇!)
这是用于需要工作的库代码 无论应用程序是否处于“屏幕兼容模式” (即在清单中 targetSdkVersion < = 10) , 我也不想做任何假设 关于状态栏的位置、大小或存在 或者其他类似的屏幕装饰。
事实是这样的:
我的手机(机器人4运行安卓4.1.2) 有540x960个物理像素, 也就是说,小彩色发光点
屏幕的尺寸以所需的单位为单位, 从触摸事件和查看测量,是 360x640当应用程序处于屏幕压缩模式时, 540x960当应用程序不在屏幕紧凑模式。 这些是我需要用程序找到的数字, 没有触摸事件或者观点去寻找它们, 但我很难找到任何 API 返回这些数字
获得的 Display 和 DisplayMetrics 对象 在各种不同的方式都声称屏幕大小 是540x960“像素” (不论是否处于屏幕压缩模式)。 具体来说,下面这些都是540x960: {宽度,高度}像素, GetSize () , GetRealSize () , Get { Width,Height }() ,
以各种方式获得的配置对象 全部说屏幕{宽度,高度} Dp = 360x614 (不论是否处于屏幕压缩模式)。 我不认为这代表了整个屏幕, 因为纵横比是错误的。 (我认为这是整个屏幕 减去状态栏,我需要整个屏幕。) 我想可以说整个屏幕是360x640dp, 尽管我不知道有什么 API 可以返回这个640
以各种方式获得的 DisplayMetrics 说“密度”是 1.0 f 当处于屏幕压缩模式时, 当不处于屏幕压缩模式时为1.5 f。
活动是
getWindow().getAttributes().{width,height}
是没有帮助的,因为它通常包含 MATCH_PARENT
而不是实际的尺寸。
但我显然可以从一个活动的
getWindow().getDecorView().getMeasured{Width,Height}()
(这实际上是令人惊讶的,因为
活动窗口的装饰视图
听着不像是占据了整个屏幕;
它看起来像是占据了屏幕,减去了状态栏)。
但我不想依靠这个,因为如果窗户被调整大小
(软键盘出现? 有人调用 window.setAttritribute () ?
或者我根本没有参加任何活动) ,
这显然是完全错误的
我知道下面的公式应该是适用的: 像素 = 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);
}
有没有更好更干净的方法 找到屏幕的大小?