如何在Android运行时根据dp或dip来确定屏幕宽度?


192

我需要使用dip / dp(在java文件中)编码android小部件的布局。在运行时,如果我的代码,

int pixel=this.getWindowManager().getDefaultDisplay().getWidth();

这将返回以像素(px)为单位的屏幕宽度。要将其转换为dp,我进行了编码:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

这似乎没有返回正确的答案。我制作了WVGA800仿真器,其屏幕分辨率为480 x800。运行仿真器并让代码打印pixel和dp的值时,两者的总和为320。该仿真器为240 dpi,其比例因子为0.75。

Answers:


376

试试这个

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

要么

谢谢@TomášHubálek

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

90
为什么有必要调用WindowManager?这段代码呢?DisplayMetrics displayMetrics = resources.getDisplayMetrics(); 浮动screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
托马什Hubálek

2
使用非常高密度的屏幕,这对我不起作用。好像它只是屏幕的一小部分。这个解决方案对我有用:stackoverflow.com/a/18712361/956975 Display display = getWindowManager()。getDefaultDisplay(); 点大小= new Point(); display.getSize(size); int width = size.x; int高度= size.y;
marienke 2014年

1
@dsdsdsdsd:context是Context类的任何实例。最值得注意的是,Activity是Context的子类(因此在Activity中使用它,在Fragment中使用getActivity())。应用程序和服务也是上下文的子类。
弗朗索瓦·POYER '16

112

我偶然发现了来自Google的这个问题,后来我找到了一个适用于API> = 13的简单解决方案。

供将来参考:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

请参阅配置类参考

编辑:如Nick Baicoianu所述,这将返回屏幕的可用宽度/高度(在大多数使用中应该是有趣的)。如果您需要实际的显示尺寸,请遵循最上面的答案。


23
使用Configuration的screenWidthDp / screenHeightDp与DisplayMetrics widthPixels / heightPixels之间的一个重要区别是Configuration返回可用的显示尺寸(减去状态栏等),而DisplayMetrics返回全屏尺寸。
Nick Baicoianu 2014年

这仅适用于API级别13及更高版本
2015年

要添加到@NickBaicoianu的注释中,getConfiguration()和getDisplayMetrics()方法都可以在多窗口模式下工作。即大小反映的是窗口的大小,而不是屏幕的大小。
nmw

7

您缺少默认密度值160。

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

换句话说,如果您在纵向模式下设计的宽度等于160dip的版式,则它将是所有ldpi / mdpi / hdpi设备上的屏幕的一半(我认为平板电脑除外)


您所回答的是我问题背后的逻辑推理。我明白了 我应该如何用Java编写代码,以便在运行时无论屏幕分辨率是多少,代码都能选择正确的dpi宽度?
Khushboo 2011年

希望这次我做对了:) DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);在Activity中使用。然后,outMetrics.density按照文档中的
Mykhailo Gaidai

6

改用这个呢?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;

6
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;

8
考虑给出一些解释
bigbounty

5

用科特琳回答:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }

4

简化为Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }

2

获得具有良好装饰的DP的屏幕宽度和高度:

步骤1:建立介面

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

步骤2:创建实施者类

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

第3步:获取活动中的宽度和高度:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();

这会返回以像素或dp为单位的高度和宽度吗?
塔斯林·奥塞尼

所谓的.density,这就是为什么它在dp中给您的原因
Ali Azaz Alam

我认为向您的应用中添加代码色调以解决简单的任务不是一个好主意
Ruslan Berozov

主席先生,由您决定是实现类还是直接对其进行编码。从定义的类中,您可以轻松提取代码以直接实现。
阿里·阿扎兹·阿拉姆

0

如果您只想了解屏幕宽度,则可以在开发人员选项中搜索“最小屏幕宽度”。您甚至可以对其进行编辑。


0

试试这个:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.