ChatGPT解决这个技术问题 Extra ChatGPT

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

我需要使用 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。


T
Top-Master

正如@Tomáš Hubálek 提到的那样;尝试类似:

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

或者

尝试旧答案:

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;

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

我偶然发现了 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() 方法都在多窗口模式下工作。即大小反映了窗口的大小,而不是屏幕的大小。
T
TheYogi

为 Kotlin 简化的 2022 答案:

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 }

但是密度在哪里。我想还需要多几行。
density 来自 run 块中的 DisplayMetrics
a
amalBit

改用这个怎么样?

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

M
Mykhailo Gaidai

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

考虑给出一些解释
B
Bolling

用科特林回答:

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

A
Ali Azaz Alam

根据 DP 获取屏幕宽度和高度,并进行一些很好的修饰:

第一步:创建接口

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
我认为在你的应用程序中添加代码色调来解决一个简单的任务不是一个好主意
先生,由您决定是实现类还是直接对其进行编码。从定义的类中,您可以轻松地提取代码以直接实现。
S
Simon Featherstone

在 Compose on a line 的新世界中

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

S
Szabolcs Becze

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

  /**
     * @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;
    }

m
math channel

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


M
Muhammed naseef Koppilakkal

尝试这个:

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

e
eldarerathis

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

做这个:

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

这个答案是不正确的。从 developer.android.com/guide/practices/…,像素 = Dp * 密度。