如何以编程方式获取android屏幕大小,一劳永逸?
如何以编程方式查找我的屏幕大小,触摸事件和视图测量/布局使用的单位? 换句话说,我需要触摸事件' getRawX()/getRawY()
和View.getLocationOnScreen()
使用的坐标系中屏幕右下角的坐标。
我很犹豫要调用所需的事件/视图单位“像素”,因为很明显,在我的手机中存在几种不同模式的“像素”概念,而且它们不会构成一致的故事。
我发现这个问题已经在stackoverflow和其他地方被问到和回答了很多,但是在所有模式下,我的手机(droid 4,android 4.1.2)都没有答案。
(哇!)
无论应用程序是否处于“屏幕兼容模式”(即清单中的targetSdkVersion <= 10),该代码都需要工作,并且我也不想对位置,大小做出任何假设,或者存在状态栏或任何其他类似的屏幕装饰。
这里是事实:
我的手机(运行android 4.1.2的droid 4)具有540x960的物理像素,即小彩色发光点。
通过查看触摸事件和查看度量,所需单位中屏幕的大小在应用程序处于屏幕共享模式时为360x640,当应用程序未处于屏幕共享模式时为540x960。 这些是我需要以编程方式查找的数字,不需要使用触摸事件或视图来查找它们,但是我很难找到任何将返回这些数字的API。
以各种方式获得的Display和DisplayMetrics对象都声称屏幕尺寸为540x960“像素”(无论是否在屏幕兼容模式下)。 具体而言,以下全部都是540x960:DisplayMetrics。{width,height}像素,Display.getSize(),Display.getRealSize(),Display.get {Width,Height}(),
以各种方式获得的配置对象都表示屏幕{宽度,高度} Dp = 360x614(不管是否处于屏幕兼容模式)。 由于纵横比是错误的,我不相信它代表整个屏幕。 (我认为这是整个屏幕减去状态栏;我需要整个屏幕)。我认为可以安全地说整个屏幕是360x640 dp,但我不知道任何返回640的API。
以各种方式获得的DisplayMetrics称在屏幕兼容模式下“密度”为1.0f,当不在屏幕兼容模式时为1.5f。
该活动的getWindow().getAttributes().{width,height}
没有帮助,因为它通常包含MATCH_PARENT
而不是实际大小。 但我显然可以从一个活动的getWindow().getDecorView().getMeasured{Width,Height}()
得到所需的答案(这实际上令人惊讶,因为活动的窗口的decorView看起来并不像整个屏幕;它看起来像占用了屏幕减去状态栏)。 但是我不想依赖这个,因为如果窗口被调整大小(出现软键盘?有人调用window.setAttributes()?或者我根本不在活动中),这显然是所有的错误。
我知道下面的公式应该是这样的:pixels = dp * density当不在屏幕兼容模式时,似乎与所有报告的数字(上面的(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);
}
有没有更好的/更清洁的方式来找到屏幕的大小?
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
现在,您可以使用像素来测量屏幕尺寸,这是比厘米更好的测量单位,因为所有按钮,文字浏览等都是在本机中测量的。 那是我通常使用的
通过使用DisplayMetrics,您可以获得任何设备的屏幕高度和宽度。 这里是代码。
DisplayMetrics metrics;
int width = 0, height = 0;
在你的onCreate方法
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
height = metrics.heightPixels;
width = metrics.widthPixels;
尝试这个。
在你的#6中,你注意到DecorView似乎提供了你想要的,但你不认为它是可靠的。 我相信你会接近你。 根据Window.getDecorView
的文档:
检索顶层窗口装饰视图(包含标准窗口框架/装饰以及其内部的客户端内容),可以将其作为窗口添加到窗口管理器。
状态栏是这里提到的窗口装饰的一部分。 软件键盘和其他覆盖层将会收到他们自己的窗口,所以他们不应该干涉相关的值。 不正确的是显示度量标准,但是如果您的应用程序是全屏显示的,它应该始终是通过兼容性转换器过滤的全屏尺寸。 其他应用程序将无法访问您的应用程序的Window
,因此无需担心其他应用程序在您未查找时更改属性。
希望有所帮助。
链接地址: http://www.djcxy.com/p/90659.html上一篇: how to get android screen size programmatically, once and for all?