如何使用代码确定设备屏幕大小类别(小,正常,大,超大)?

321
有没有办法确定当前设备屏幕尺寸的类别,比如小、正常、大、特大? 不是密度,而是屏幕尺寸。
10个回答

428
您可以使用 Configuration.screenLayout 位掩码。
示例:
if ((getResources().getConfiguration().screenLayout & 
    Configuration.SCREENLAYOUT_SIZE_MASK) == 
        Configuration.SCREENLAYOUT_SIZE_LARGE) {
    // on a large screen device ...

}

32
为了实现对x-large的检测,请确保在您的项目中使用目标android-3.0。或者,可以将静态值4用于x-large。 - Peterdk
5
有些设备的屏幕大小是未定义的,因此检查 Configuration.SCREENLAYOUT_SIZE_UNDEFINED 也可能很有用。 - valerybodak
你能使用 >= 来获取大于或等于某个尺寸的屏幕吗? - Andrew S

152

下面的代码完善了上面的答案,将屏幕尺寸显示为 Toast。

//Determine screen size
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
    Toast.makeText(this, "Large screen", Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
    Toast.makeText(this, "Normal sized screen", Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
    Toast.makeText(this, "Small sized screen", Toast.LENGTH_LONG).show();
}
else {
    Toast.makeText(this, "Screen size is neither large, normal or small", Toast.LENGTH_LONG).show();
}

以下代码将屏幕密度显示为 Toast。

//Determine density
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int density = metrics.densityDpi;

if (density == DisplayMetrics.DENSITY_HIGH) {
    Toast.makeText(this, "DENSITY_HIGH... Density is " + String.valueOf(density), Toast.LENGTH_LONG).show();
}
else if (density == DisplayMetrics.DENSITY_MEDIUM) {
    Toast.makeText(this, "DENSITY_MEDIUM... Density is " + String.valueOf(density), Toast.LENGTH_LONG).show();
}
else if (density == DisplayMetrics.DENSITY_LOW) {
    Toast.makeText(this, "DENSITY_LOW... Density is " + String.valueOf(density), Toast.LENGTH_LONG).show();
}
else {
    Toast.makeText(this, "Density is neither HIGH, MEDIUM OR LOW.  Density is " + String.valueOf(density), Toast.LENGTH_LONG).show();
}

68

Jeff Gilfelt 的答案作为一个静态辅助方法:

private static String getSizeName(Context context) {
    int screenLayout = context.getResources().getConfiguration().screenLayout;
    screenLayout &= Configuration.SCREENLAYOUT_SIZE_MASK;

    switch (screenLayout) {
    case Configuration.SCREENLAYOUT_SIZE_SMALL:
        return "small";
    case Configuration.SCREENLAYOUT_SIZE_NORMAL:
        return "normal";
    case Configuration.SCREENLAYOUT_SIZE_LARGE:
        return "large";
    case 4: // Configuration.SCREENLAYOUT_SIZE_XLARGE is API >= 9
        return "xlarge";
    default:
        return "undefined";
    }
}

12
private String getDeviceDensity() {
    int density = mContext.getResources().getDisplayMetrics().densityDpi;
    switch (density)
    {
        case DisplayMetrics.DENSITY_MEDIUM:
            return "MDPI";
        case DisplayMetrics.DENSITY_HIGH:
            return "HDPI";
        case DisplayMetrics.DENSITY_LOW:
            return "LDPI";
        case DisplayMetrics.DENSITY_XHIGH:
            return "XHDPI";
        case DisplayMetrics.DENSITY_TV:
            return "TV";
        case DisplayMetrics.DENSITY_XXHIGH:
            return "XXHDPI";
        case DisplayMetrics.DENSITY_XXXHIGH:
            return "XXXHDPI";
        default:
            return "Unknown";
    }
}

2
这会获取屏幕的密度。问题指定“不是密度,而是屏幕尺寸”。 - Subaru Tashiro

11

非常感谢以上的答案,对我帮助很大 :-) 但是对于那些(像我一样)仍然需要支持Android 1.5的人,我们可以使用Java反射来实现向后兼容:

Configuration conf = getResources().getConfiguration();
int screenLayout = 1; // application default behavior
try {
    Field field = conf.getClass().getDeclaredField("screenLayout");
    screenLayout = field.getInt(conf);
} catch (Exception e) {
    // NoSuchFieldException or related stuff
}
// Configuration.SCREENLAYOUT_SIZE_MASK == 15
int screenType = screenLayout & 15;
// Configuration.SCREENLAYOUT_SIZE_SMALL == 1
// Configuration.SCREENLAYOUT_SIZE_NORMAL == 2
// Configuration.SCREENLAYOUT_SIZE_LARGE == 3
// Configuration.SCREENLAYOUT_SIZE_XLARGE == 4
if (screenType == 1) {
    ...
} else if (screenType == 2) {
    ...
} else if (screenType == 3) {
    ...
} else if (screenType == 4) {
    ...
} else { // undefined
    ...
}

2
您可以针对平台的最新版本,并从“Configuration”类中引用常量。这些是静态不变的值,将在编译时内联(即它们将被其实际值替换),因此您的代码不会在旧版本的平台上出现故障。 - Karakuri
不错,我不知道那个... 你是在说 android:targetSdkVersion 吗? - A. Masson
1
是的,这就是如何针对特定版本进行目标定位。大多数人(至少我见过的)将他们的“targetSdkVersion”设置为最新版本。 - Karakuri
领域的进口是什么?这对于使其正常运行非常重要。 - undefined

6

2018年,如果您需要Jeff用Kotlin的回答,这里是:

  private fun determineScreenSize(): String {
    // Thanks to https://dev59.com/-G445IYBdhLWcg3wJ258#5016350.
    val screenLayout = resources.configuration.screenLayout
    return when {
      screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK == Configuration.SCREENLAYOUT_SIZE_SMALL -> "Small"
      screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK == Configuration.SCREENLAYOUT_SIZE_NORMAL -> "Normal"
      screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK == Configuration.SCREENLAYOUT_SIZE_LARGE -> "Large"
      screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK == Configuration.SCREENLAYOUT_SIZE_XLARGE -> "Xlarge"
      screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK == Configuration.SCREENLAYOUT_SIZE_UNDEFINED -> "Undefined"
      else -> error("Unknown screenLayout: $screenLayout")
    }
  }

5

需要检查超大屏幕和高分辨率吗?这是所选答案的修改代码。

//Determine screen size
if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {     
    Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show();
} else if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {     
    Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show();
} else if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {     
    Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show();
} else if ((getResources().getConfiguration().screenLayout &      Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {     
    Toast.makeText(this, "XLarge sized screen" , Toast.LENGTH_LONG).show();
} else {
    Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show();
}

//Determine density
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int density = metrics.densityDpi;

if (density==DisplayMetrics.DENSITY_HIGH) {
    Toast.makeText(this, "DENSITY_HIGH... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else if (density==DisplayMetrics.DENSITY_MEDIUM) {
    Toast.makeText(this, "DENSITY_MEDIUM... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else if (density==DisplayMetrics.DENSITY_LOW) {
    Toast.makeText(this, "DENSITY_LOW... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else if (density==DisplayMetrics.DENSITY_XHIGH) {
    Toast.makeText(this, "DENSITY_XHIGH... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else if (density==DisplayMetrics.DENSITY_XXHIGH) {
    Toast.makeText(this, "DENSITY_XXHIGH... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else if (density==DisplayMetrics.DENSITY_XXXHIGH) {
    Toast.makeText(this, "DENSITY_XXXHIGH... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
} else {
    Toast.makeText(this, "Density is neither HIGH, MEDIUM OR LOW.  Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
}

[密度] 在这种情况下,您需要处于活动状态。如果您在外部,请使用getWindowManager()此代码 WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); - horkavlna

4
这是一个Xamarin.Android版本的Tom McFarlin的答案,具体内容请参考这里
        //Determine screen size
        if ((Application.Context.Resources.Configuration.ScreenLayout & ScreenLayout.SizeMask) == ScreenLayout.SizeLarge) {
            Toast.MakeText (this, "Large screen", ToastLength.Short).Show ();
        } else if ((Application.Context.Resources.Configuration.ScreenLayout & ScreenLayout.SizeMask) == ScreenLayout.SizeNormal) {
            Toast.MakeText (this, "Normal screen", ToastLength.Short).Show ();
        } else if ((Application.Context.Resources.Configuration.ScreenLayout & ScreenLayout.SizeMask) == ScreenLayout.SizeSmall) {
            Toast.MakeText (this, "Small screen", ToastLength.Short).Show ();
        } else if ((Application.Context.Resources.Configuration.ScreenLayout & ScreenLayout.SizeMask) == ScreenLayout.SizeXlarge) {
            Toast.MakeText (this, "XLarge screen", ToastLength.Short).Show ();
        } else {
            Toast.MakeText (this, "Screen size is neither large, normal or small", ToastLength.Short).Show ();
        }
        //Determine density
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager.DefaultDisplay.GetMetrics (metrics);
        var density = metrics.DensityDpi;
        if (density == DisplayMetricsDensity.High) {
            Toast.MakeText (this, "DENSITY_HIGH... Density is " + density, ToastLength.Long).Show ();
        } else if (density == DisplayMetricsDensity.Medium) {
            Toast.MakeText (this, "DENSITY_MEDIUM... Density is " + density, ToastLength.Long).Show ();
        } else if (density == DisplayMetricsDensity.Low) {
            Toast.MakeText (this, "DENSITY_LOW... Density is " + density, ToastLength.Long).Show ();
        } else if (density == DisplayMetricsDensity.Xhigh) {
            Toast.MakeText (this, "DENSITY_XHIGH... Density is " + density, ToastLength.Long).Show ();
        } else if (density == DisplayMetricsDensity.Xxhigh) {
            Toast.MakeText (this, "DENSITY_XXHIGH... Density is " + density, ToastLength.Long).Show ();
        } else if (density == DisplayMetricsDensity.Xxxhigh) {
            Toast.MakeText (this, "DENSITY_XXXHIGH... Density is " + density, ToastLength.Long).Show ();
        } else {
            Toast.MakeText (this, "Density is neither HIGH, MEDIUM OR LOW.  Density is " + density, ToastLength.Long).Show ();
        }

4
请尝试使用此函数 isLayoutSizeAtLeast(int screenSize)

要检查小屏幕,至少为320x426 dp及以上 getResources().getConfiguration().isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_SMALL);

要检查普通屏幕,至少为320x470 dp及以上 getResources().getConfiguration().isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_NORMAL);

要检查大屏幕,至少为480x640 dp及以上 getResources().getConfiguration().isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);

要检查超大屏幕,至少为720x960 dp及以上 getResources().getConfiguration().isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE);


不错!该方法早在API 11级就可用了! - Enselic

1

你能否使用字符串资源和枚举来实现这个功能呢?你可以定义一个名为屏幕大小的字符串资源,例如 SMALL、MEDIUM 或 LARGE。然后,你可以使用字符串资源的值来创建枚举的实例。

  1. 在您的代码中定义一个枚举,列出您所关心的不同屏幕尺寸。

    public Enum ScreenSize {
        SMALL,
        MEDIUM,
        LARGE,;
    }
    
  2. 定义一个字符串资源,比如说screensize,其值将是SMALL、MEDIUM或LARGE。

    <string name="screensize">MEDIUM</string>
    
  3. 在您关心的每个维度上,都将screensize的副本放入一个字符串资源中。
    例如,<string name="screensize">MEDIUM</string>应放在values-sw600dp/strings.xml和values-medium/strings.xml中,而<string name="screensize">LARGE</string>应放在sw720dp/strings.xml和values-large/strings.xml中。
  4. 在代码中编写:
    ScreenSize size = ScreenSize.valueOf(getReources().getString(R.string.screensize);

这很有前途... 但是我已经用3个设备进行了测试,平板仍然返回SMALL,而我期望的是LARGE。我的string.xml文件定义在values-h1024dp、values-h700dp和values-h200dp内,对应的<string name="screensize">xxxxxx</string>。 - A. Masson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接