如何一劳永逸地以编程方式获取android屏幕尺寸?
Posted
技术标签:
【中文标题】如何一劳永逸地以编程方式获取android屏幕尺寸?【英文标题】:how to get android screen size programmatically, once and for all? 【发布时间】:2013-07-03 02:40:47 【问题描述】:如何以编程方式找出我的屏幕尺寸,
在触摸事件使用的单位中
和查看测量/布局?
换句话说,我想要坐标
屏幕右下角的,
在触摸事件使用的坐标系中'
getRawX()/getRawY()
和 View.getLocationOnScreen()
。
我不愿将所需的事件/视图单位称为“像素” 因为显然有几个“像素”的概念 在我的手机上以各种模式, 而且它们并没有形成一个一致的故事。
我看到这个问题已经被问过很多次了 在***和其他地方, 但没有的答案实际上在我的手机上有效 (droid 4, android 4.1.2) 在所有模式下:
Can I find out width of screen programmatically in android app? How do I get the ScreenSize programmatically in android Android set View visibility programmatically based on screen size How do I get the height of the screen in Android? Get the screen height in 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 and setting width and height programmatically in dp units http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatically-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-programmatically(哇!)
这适用于需要工作的库代码 无论应用是否处于“屏幕兼容模式” (即清单中的 targetSdkVersion
以下是事实:
我的手机(运行 android 4.1.2 的 droid 4) 具有 540x960 物理像素, 即小彩色发光点。
以所需单位显示的屏幕尺寸, 通过查看触摸事件和查看测量,是 360x640 当应用处于屏幕兼容模式时, 当应用程序未处于屏幕兼容模式时为 540x960。 这些是我需要以编程方式找到的数字, 无需使用触摸事件或视图来查找它们, 但我很难找到任何 API 这将返回这些数字。
已获得 Display 和 DisplayMetrics 对象 以各种方式都声称屏幕尺寸 是 540x960“像素” (无论是否在屏幕兼容模式下)。 具体来说,以下都是 540x960: DisplayMetrics.width,height像素, 显示.getSize(), Display.getRealSize(), Display.getWidth,Height(),
通过各种方式获得的配置对象 都说屏幕Width,HeightDp = 360x614 (无论是否在屏幕兼容模式下)。 我不相信那代表整个屏幕, 因为纵横比是错误的。 (我认为是整个屏幕 减去状态栏;我需要整个屏幕。) 我认为可以肯定地说整个屏幕是 360x640 dp, 虽然我不知道任何返回 640 的 API。
DisplayMetrics 以各种方式获得 说“密度”是 1.0f 在屏幕兼容模式下, 不处于屏幕兼容模式时为 1.5f。
活动的
getWindow().getAttributes().width,height
没有帮助,因为它通常包含 MATCH_PARENT
而不是实际尺寸。
但我显然可以从活动中得到想要的答案
getWindow().getDecorView().getMeasuredWidth,Height()
(这实际上令人惊讶,因为
活动窗口的 decorView
看起来不像是占据了整个屏幕;
看起来它正在占用屏幕减去状态栏)。
但我不想依赖这个,因为如果窗口被调整大小
(出现软键盘?有人调用 window.setAttributes()?
或者我可能根本不在活动中),
这显然是错误的。
我了解以下公式应该成立: 像素 = dp * 密度 这似乎与所有报告的数字一致(上面的(3),(4),(5)) 当 not 处于屏幕兼容模式时: 540x960 = 360x640 * 1.5 但在屏幕兼容模式下,它不会加起来: 540x960 != 360x640 * 1 所以,有些不对劲。
我认为最简单的解释是, 就是上面(3)中列出的方法 只是在“像素”时给出错误的答案 在屏幕兼容模式下——也就是说,它们是有意的 返回 360x640“像素”,但他们错误地返回 540x960。 但可能还有其他方式来看待它。
在任何情况下,无论模式如何,都能获得所需的数字, 从上面的拼图来看,肯定是一个棘手的难题。 我找到了一种似乎在两种模式下都可以在手机上使用的方法, 但它非常迂回, 它依赖于两个看起来仍然相当不稳定的假设 (如下面的代码 cmets 所述)。
这是我的食谱:
/** 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);
有没有更好/更清洁的方法 找到屏幕的大小??
【问题讨论】:
+1 很好的问题,并且展示了很多研究工作。 @Don 在docs 中,解释说兼容模式将停止对旧设置进行“缩放以适应”操作。但是,根据您的观察,没有清楚地解释“它是如何工作的”,我认为它们只是关闭了密度缩放,即:1px 变为 1dp。可能这种变化只发生在渲染部分,DisplayMetrics
永远不会更新这种变化。有类似this 的问题已经提交。
@user117 - 有趣。好吧,DisplayMetrics 的 部分 至少得到了更新——密度更改为 1.0。但是 widthPixels/heightPixels 似乎并没有被更改为匹配。关于引用的问题,看起来行为恢复到 3.1 行为(即我看到 heightPixels include 状态栏......但似乎单位错误)
@DonHatch 谢谢,好心——我实际上是想赞扬一个深思熟虑的问题,奇怪的是在 StackExchange 上不那么受欢迎——请注意这个问题不仅仅是“真实”的问题答案,讲的是听众对该主题的知识的(低)质量。现在,我可能会因为自己的问题因“不真实”而被一个接一个地关闭而受到创伤,幽默感可能让我失望,但它开始看起来像是有“好”答案的问题真的是这一切都在这里发生了什么......当然,我赞成你的:)
顺便说一句!这是我怀疑的内容:@ 987654336@(尤其是参见他的(1)点,即快速制作的答案——实际上就是这个Q的情况!)。无论如何,快乐的纽约(我的在 11 分钟内到来)! :)
【参考方案1】:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
现在您可以以像素为单位测量屏幕尺寸,这是比厘米更好的测量单位,因为所有按钮、文本视图等都是以该单位测量的。我平时用的那个
【讨论】:
根据Op(特别是第3点),这在屏幕兼容模式下不会不正确吗?【参考方案2】:通过使用 DisplayMetrics,您可以获得任何设备屏幕的高度和宽度。请注意,宽度和高度对旋转很敏感。 这是代码。
DisplayMetrics metrics;
int width = 0, height = 0;
在你的 onCreate 方法中
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
height = Math.min(metrics.widthPixels, metrics.heightPixels); //height
width = Math.max(metrics.widthPixels, metrics.heightPixels); //width
试试这个。
【讨论】:
不,正如我在 (3) 中所说,指标。width,heightPixels 在屏幕兼容模式下不给出正确答案。 我还发现:似乎 lite metrics.heightPixels 可能会在屏幕旋转的情况下给出宽度,反之亦然!【参考方案3】:在您的 #6 中,您注意到 DecorView 似乎提供了您想要的东西,但您认为它不可靠。我相信这是尽可能接近的。根据Window.getDecorView
的文档:
检索顶层窗口装饰视图(包含标准窗口框架/装饰和其中的客户端内容),可以将其作为窗口添加到窗口管理器。
状态栏是那里提到的窗口装饰的一部分。软件键盘和其他覆盖将接收自己的窗口,因此它们不应干扰相关值。正确的不是精确的显示指标,但如果您的应用程序是全屏的,它应该始终是通过兼容性转换器过滤的全屏尺寸。其他应用程序无法访问您的应用程序的Window
,因此无需担心其他应用程序会在您不查看时更改属性。
希望对您有所帮助。
【讨论】:
【参考方案4】:我应该将此作为评论,但我没有代表。 这可能不是一个完全正确的答案,但是当我在 DisplayMetrics 方法中切换高度和宽度时,我得到了我的尺寸。
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.heightPixels;
height = metrics.widthPixels;
正如我所说,这可能不正确,但我不知道为什么,但它对我有用。
【讨论】:
我相信这是因为你的屏幕已经旋转了。 不相信我。【参考方案5】:如果您使用 17 级或更高级别的 API,请查看 Display 中的 getRealMetrics 和 getRealSize
对于 api 级别 14,15 和 16,请查看 here
【讨论】:
【参考方案6】:我已经使用毕达哥拉斯定理找到了 Android 手机/平板电脑屏幕的对角线尺寸,同样的原理可以应用于 iPhone 或 Blackberry 屏幕。
DisplayMetrics met = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(met);// get display metrics object
String strSize =
new DecimalFormat("##.##").format(Math.sqrt(((met.widthPixels / met.xdpi) *
(met.widthPixels / met.xdpi)) +
((met.heightPixels / met.ydpi) * (met.heightPixels / met.ydpi))));
// using Dots per inches with width and height
毕达哥拉斯一定是个天才,他多年前就知道智能手机编程:p
【讨论】:
【参考方案7】:我使用下面的方法来获取设备的宽度:
public static int getDeviceWidth(Context context)
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width=display.getWidth();
return width;
【讨论】:
此方法已弃用。请使用 displaymetrics 方法。【参考方案8】:我认为这个功能将帮助您简单地获取您的 android 屏幕尺寸的宽度和高度。该函数将宽度和高度作为整数数组返回,如下所示
private int[] getScreenSIze()
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
int w = displaymetrics.widthPixels;
int[] size=w,h;
return size;
并在您的创建方法上输出您的宽度和高度,如下所示
int[] screenSize= getScreenSIze();
int width=screenSize[0];
int height=screenSize[1];
screenSizes.setText("Phone Screen sizes \n\n width = "+width+" \n Height = "+height);
Download source code 并在您的 android studio 上进行测试
【讨论】:
【参考方案9】:这对我有用:
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int height = Resources.getSystem().getDisplayMetrics().heightPixels;
我用它在水平回收器视图中更新我的项目的宽度。(根据我的要求) 希望它可以帮助某人!
【讨论】:
【参考方案10】:对于 Kotlin 中的这个解决方案,试试这个:
private fun yourFunction()
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
val width = metrics.widthPixels
val height = metrics.heightPixels
【讨论】:
以上是关于如何一劳永逸地以编程方式获取android屏幕尺寸?的主要内容,如果未能解决你的问题,请参考以下文章