如何通过编程获得 Android 屏幕大小,一劳永逸?

如何通过编程查找屏幕大小, 触摸事件所使用的单位 查看测量/布局? 换句话说,我要坐标 在屏幕的右下角, 在触摸事件使用的坐标系中 getRawX()/getRawY()View.getLocationOnScreen()

我在犹豫是否将所需的事件/视图单元称为“像素” 因为显然有几个“像素”的概念 在我的手机上用各种模式, 他们的说法并不一致。

我知道这个问题已经得到了很多回答 堆栈溢出和其他地方, 但是 没有的答案在我的手机上是有效的 (droid4,android 4.1.2)所有模式:

(哇!)

这是用于需要工作的库代码 无论应用程序是否处于“屏幕兼容模式” (即在清单中 targetSdkVersion < = 10) , 我也不想做任何假设 关于状态栏的位置、大小或存在 或者其他类似的屏幕装饰。


事实是这样的:

  1. 我的手机(机器人4运行安卓4.1.2) 有540x960个物理像素, 也就是说,小彩色发光点

  2. 屏幕的尺寸以所需的单位为单位, 从触摸事件和查看测量,是 360x640当应用程序处于屏幕压缩模式时, 540x960当应用程序不在屏幕紧凑模式。 这些是我需要用程序找到的数字, 没有触摸事件或者观点去寻找它们, 但我很难找到任何 API 返回这些数字

  3. 获得的 Display 和 DisplayMetrics 对象 在各种不同的方式都声称屏幕大小 是540x960“像素” (不论是否处于屏幕压缩模式)。 具体来说,下面这些都是540x960: {宽度,高度}像素, GetSize () , GetRealSize () , Get { Width,Height }() ,

  4. 以各种方式获得的配置对象 全部说屏幕{宽度,高度} Dp = 360x614 (不论是否处于屏幕压缩模式)。 我不认为这代表了整个屏幕, 因为纵横比是错误的。 (我认为这是整个屏幕 减去状态栏,我需要整个屏幕。) 我想可以说整个屏幕是360x640dp, 尽管我不知道有什么 API 可以返回这个640

  5. 以各种方式获得的 DisplayMetrics 说“密度”是 1.0 f 当处于屏幕压缩模式时, 当不处于屏幕压缩模式时为1.5 f。

  6. 活动是 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);
}

有没有更好更干净的方法 找到屏幕的大小?

70158 次浏览

通过使用 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

试试这个。

如果您使用 api 级别17或更高,请查看 展示中的 getRealMetrics 和 getRealSize

对于 api 水平14,15和16看 给你

在您的 # 6中,您注意到 DecorView 似乎提供了您想要的东西,但您认为它是不可行的。我相信你已经尽力了。根据 Window.getDecorView的文件:

检索顶级窗口装饰视图(包含标准的窗口框架/装饰和其中的客户端内容) ,它可以作为窗口添加到窗口管理器。

状态栏是上面提到的窗口装饰的一部分。软件键盘和其他覆盖图将收到自己的窗口,所以他们不应该干扰相关的值。准确地说,并不是显示指标,但是如果应用程序是全屏的,那么应该始终是通过兼容性转换器过滤的全屏大小。其他应用程序无法访问您的应用程序的 Window,因此不必担心其他应用程序在您不注意的时候改变属性。

希望能帮上忙。

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

现在你可以用像素来测量你的屏幕尺寸,这是一个比厘米更好的测量单位,因为所有的按钮,文本视图等。用这个单位来衡量。那是我平时用的

我已经用毕达哥拉斯定理找到了 Android 手机/平板电脑屏幕的对角线尺寸,同样的原理也适用于 iPhone 或黑莓手机屏幕。

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

毕达哥拉斯一定是个天才,他在很多年前就知道智能手机编程了

我应该把这作为一个评论,但我没有这方面的代表。
这可能不是一个完全正确的答案,但是当我在 DisplayMetrics 方法中切换高度和宽度时,我得到了我的尺寸。

    DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.heightPixels;
height = metrics.widthPixels;

正如我所说,这可能不正确,但我不知道为什么,但它为我工作。

我使用下面的方法得到设备的宽度:

public static int getDeviceWidth(Context context){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width=display.getWidth();
return width;
}

我认为这个函数将帮助你简单地得到你的 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);

下载源代码 并在您的 android 工作室中进行测试

对于 科特林中的这个解决方案,请尝试以下操作:

private fun yourFunction(){
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
val width = metrics.widthPixels
val height = metrics.heightPixels
}

这对我有用:

Int width = Resources.getSystem () . getDisplayMetrics () . widthPixels;

Int height = Resources.getSystem () . getDisplayMetrics () . heightPixels;

我使用这个来更新我的项目的宽度在一个水平回收视图。(根据我的要求) 希望能帮到别人!