【问题标题】:How to determine the screen width in terms of dp or dip at runtime in Android?如何在 Android 运行时根据 dp 或 dip 确定屏幕宽度?
【发布时间】:2011-06-24 09:06:55
【问题描述】:

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

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

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

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

这似乎没有返回正确的答案。我制作了 WVGA800 的模拟器,它的屏幕分辨率为 480 x 800。当运行模拟器并让代码打印像素和 dp 的值时,两者都达到了 320。该模拟器为 240 dpi,其比例因子为 0.75。

【问题讨论】:

    标签: android density-independent-pixel


    【解决方案1】:

    试试这个

    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;
    

    【讨论】:

    • 为什么要调用WindowManager?这段代码呢? DisplayMetrics displayMetrics = resources.getDisplayMetrics(); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
    • 这对我使用非常高密度的屏幕不起作用。就好像它只占据了屏幕的一小部分。这个解决方案对我有用:stackoverflow.com/a/18712361/956975 Display display = getWindowManager().getDefaultDisplay();点大小 = new Point(); display.getSize(大小); int 宽度 = size.x; int height = size.y;
    • @dsdsdsdsd : context 是 Context 类的任何实例。最值得注意的是,Activity 是 Context 的子类(因此在 Activity 中使用它,在 Fragment 中使用 getActivity())。 Application 和 Service 也是 Context 的子类。
    【解决方案2】:

    我偶然发现了 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.
    

    Configuration class reference

    编辑:正如 Nick Baicoianu 所指出的,这将返回屏幕的可用宽度/高度(这应该是大多数用途中有趣的)。如果您需要实际显示尺寸,请坚持最佳答案。

    【讨论】:

    • 使用 Configuration 的 screenWidthDp/screenHeightDp 与 DisplayMetrics widthPixels/heightPixels 的一个重要区别是 Configuration 返回 可用 显示尺寸(减去状态栏等),而 DisplayMetrics 返回全屏尺寸。
    • 这仅适用于 API 级别 13 及以上
    • 要添加到@NickBaicoianu 的评论中,getConfiguration() 和 getDisplayMetrics() 方法都可以在多窗口模式下工作。即大小反映的是窗口的大小,而不是屏幕的大小。
    【解决方案3】:

    2022 为 Kotlin 简化的答案:

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

    或单线:

    val (height, width) = resources.displayMetrics.run { heightPixels/density to widthPixels/density }
    

    【讨论】:

      【解决方案4】:

      改用这个怎么样?

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

      【讨论】:

        【解决方案5】:

        您缺少 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 宽度?
        • 希望这次我做对了 :) 在活动中使用DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);。然后,outMetrics.density 将为您提供当前设备的比例因子,如 docs 中所述
        【解决方案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;
        

        【讨论】:

        • 考虑解释一下
        【解决方案7】:

        在 kotlin 中回答:

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

        【讨论】:

          【解决方案8】:

          根据 DP 获得屏幕宽度和高度,并带有一些很好的装饰:

          第 1 步:创建接口

          public interface ScreenInterface {
          
             float getWidth();
          
             float getHeight();
          
          }
          

          第二步:创建实现类

          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
          • 我认为在你的应用中添加代码来解决一个简单的任务并不是一个好主意
          • 先生,是实现类还是直接编写代码取决于您。从定义的类中,您可以轻松提取代码以直接实现。
          【解决方案9】:

          这是一个基于先前响应的复制/粘贴功能。

            /**
               * @param context
               * @return the Screen height in DP
               */
              public static float getHeightDp(Context context) {
                  DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
                  float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
                  return dpHeight;
              }
          
              /**
               * @param context
               * @return the screnn width in dp
               */
              public static float getWidthDp(Context context) {
                  DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
                  float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
                  return dpWidth;
              }
          

          【讨论】:

            【解决方案10】:

            在 Compose on a line 的新世界中

            val (height, width) = LocalConfiguration.current.run { screenHeightDp.dp to screenWidthDp.dp }
            

            【讨论】:

              【解决方案11】:

              如果您只想了解自己的屏幕宽度,可以在开发者选项中搜索“最小屏幕宽度”。你甚至可以编辑它。

              【讨论】:

                【解决方案12】:

                试试这个:

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

                【讨论】:

                  【解决方案13】:

                  您的问题是将浮点数转换为 int,从而失去精度。您还应该乘以因子而不是除以。

                  这样做:

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

                  【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-06-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多