如何以触摸事件和查看测量/布局使用的单位以编程方式查找屏幕尺寸?换句话说,我想在屏幕的右下角的坐标,通过触摸事件所使用的坐标系中
getRawX()/getRawY()和View.getLocationOnScreen().
我不愿意将所需的事件/视图单位称为"像素",因为在我的手机上有各种模式的"像素"概念,并且它们并没有达到一致的故事.
我看到这已经被问到并在stackoverflow和其他地方得到了很多回答,但在所有模式下,我的手机(droid 4,android 4.1.2)上没有任何答案实际可行:
(哇!)
这适用于需要工作的库代码,无论应用程序是否处于"屏幕兼容模式"(即清单中的targetSdkVersion <= 10),我也不想对位置,大小做任何假设,或存在状态栏或任何其他类似的屏幕装饰.
以下是事实:
我的手机(机器人4运行Android 4.1.2)有540x960物理像素,即小彩色发光点.
当应用程序处于屏幕比较模式时,所需单位的屏幕大小(从查看触摸事件和查看测量值)为360x640,当应用程序未处于屏幕比较模式时为540x960.这些是我需要以编程方式找到的数字,而不是用触摸事件或视图来查找它们,但是我很难找到任何会返回这些数字的API.
以各种方式获得的显示和DisplayMetrics对象均声称屏幕尺寸为540x960"像素"(无论是否在屏幕比较模式下).具体来说,以下都是540x960:DisplayMetrics.{width,height} Pixels,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()?或者我可能根本不在Activity中),这显然是全部错误.
我理解以下公式应该保持: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);
}
Run Code Online (Sandbox Code Playgroud)
有没有更好/更清洁的方法来找到屏幕的大小?
Cob*_*a47 41
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Run Code Online (Sandbox Code Playgroud)
现在,您可以以像素为单位测量屏幕尺寸,这是一个比厘米更好的测量单位,因为所有按钮,文本视图等都是在此单位中测量的.那是我正常使用的
通过使用DisplayMetrics,您可以获得任何设备屏幕的高度和宽度.这是代码.
DisplayMetrics metrics;
int width = 0, height = 0;
Run Code Online (Sandbox Code Playgroud)
在你的onCreate方法中
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
height = Math.min(metrics.widthPixels, metrics.heightPixels); //height
width = Math.max(metrics.widthPixels, metrics.heightPixels); //width
Run Code Online (Sandbox Code Playgroud)
试试这个.
在你的#6中,你注意到DecorView似乎提供了你想要的东西,但是你认为它并不可行.我相信这就是你能来的尽可能接近.根据以下文件Window.getDecorView:
检索顶级窗口装饰视图(包含标准窗口框架/装饰和其中的客户端内容),可以将其作为窗口添加到窗口管理器.
状态栏是那里提到的窗口装饰的一部分.软件键盘和其他叠加层将接收自己的窗口,因此它们不应干扰相关值.这是正确的,不完全是显示指标,但如果您的应用程序是全屏,它应该始终是通过兼容性转换器过滤的全屏大小.其他应用程序无法访问您的应用程序Window,因此无需担心其他应用程序在您不查看时更改属性.
希望有所帮助.
我应该把它作为评论,但我没有代表。
这可能不是一个完全正确的答案,但是当我在 DisplayMetrics 方法中切换高度和宽度时,我得到了尺寸。
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.heightPixels;
height = metrics.widthPixels;
Run Code Online (Sandbox Code Playgroud)
正如我所说,这可能不正确,但我不知道为什么,但它对我有用。
| 归档时间: |
|
| 查看次数: |
63004 次 |
| 最近记录: |