默认显示的吸气剂:显示!已弃用。在 Java 中已弃用

Sas*_*ata 24 android android-layout kotlin

我需要屏幕的宽度。但最近发现 Android 已defaultDisplay弃用消息:

默认显示的吸气剂:显示!已弃用。在 Java 中已弃用

代码:

val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
return displayMetrics.heightPixels

Run Code Online (Sandbox Code Playgroud)

请提出一个替代方案。

小智 34

defaultDisplay在 API 级别 30 (Android R) 及更高版本中被标记为已弃用。这意味着如果您的最低 SDK 配置低于 API 级别 30,则您应该同时使用旧的弃用代码和新的推荐代码实现。

正确解决问题后,您可以使用@Suppress("DEPRECATION") 来抑制警告

示例:Kotlin 解决方案

    val outMetrics = DisplayMetrics()

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
        val display = activity.display
        display?.getRealMetrics(outMetrics)
    } else {
        @Suppress("DEPRECATION")
        val display = activity.windowManager.defaultDisplay
        @Suppress("DEPRECATION")
        display.getMetrics(outMetrics)
    }
Run Code Online (Sandbox Code Playgroud)

  • getRealMetrics() 在 API 级别 31 上已弃用。 (26认同)
  • 请不要仅发布代码作为答案,还要提供解释您的代码的作用以及它如何解决问题的问题。带解释的答案通常更有帮助、质量更好,并且更有可能吸引点赞 (2认同)

小智 8

此方法在 API 级别 30 中已弃用。

使用Context.getDisplay()来代替。

不推荐使用的方法:getDefaultDisplay

新方法:getDisplay

  • 我猜/希望他们很快就会将其添加到“androidx.core”库中。我刚刚检查了最新的源代码,但我没有找到任何东西(他们实际上[抑制了使用它的类中的弃用警告](https://android.googlesource.com/platform/frameworks/support/+/ ed18608fa10d09eade8ccb879011ca8bd5fef7a1)) (4认同)
  • 但这表示:调用需要 API 级别 R (2认同)

Dav*_*uel 6

WindowManager.getDefaultDisplay()在 API 级别 30 中已弃用,以支持Context.getDisplay()需要最低 API 级别 30 的方法。

目前,androidx.core.content.ContextCompat似乎没有提供任何向后兼容的getDisplay()方法。

如果您只需要检索默认显示,而不是像其他答案建议的那样针对不同的 API 级别使用不同的方法,您可以使用 DisplayManager.getDisplay(Display.DEFAULT_DISPLAY)方法(自 API 17 起支持)来实现相同的结果。

弃用的代码:

val windowManager = getSystemService<WindowManager>()!!
val defaultDisplay = windowManager.defaultDisplay
Run Code Online (Sandbox Code Playgroud)

新代码:

val displayManager = getSystemService<DisplayManager>()!!
val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY)
Run Code Online (Sandbox Code Playgroud)

参考:androidx.core 源代码


如果您需要的是获取窗口的大小,新的Jetpack WindowManager 库为新旧平台版本的新窗口管理器功能(例如可折叠设备和 Chrome OS)提供了一个通用 API 表面。

  • WindowManager.getCurrentWindowMetrics():WindowMetrics根据当前系统状态返回。这些指标描述了窗口将占据的区域大小、MATCH_PARENT宽度和高度以及允许窗口延伸到显示切口后面的任何标志组合。
  • WindowManager.getMaximumWindowMetrics(): 返回WindowMetrics应用程序在当前系统状态下可能期望的最大值。这个值基于系统的最大潜在窗口状态。例如,对于多窗口模式下的活动,返回的指标基于用户扩展窗口以覆盖整个屏幕时的边界。

示例代码(参考):

dependencies {
    implementation "androidx.window:window:1.0.0-beta01"
}

import androidx.window.WindowManager

val vm = WindowManager(context)
vm.currentWindowMetrics.bounds // E.g. [0 0 1350 1800]
vm.maximumWindowMetrics.bounds 
Run Code Online (Sandbox Code Playgroud)


Sha*_*ark 6

尝试这样的事情:


    private Display getDisplay(@NonNull WindowManager windowManager) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // This one (context) may or may not have a display associated with it, due to it being
            // an application context
            return getDisplayPostR();
        } else {
            return getDisplayPreR(windowManager);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.R)
    private Display getDisplayPostR() {
        // We can't get the WindowManager by using the context we have, because that context is a
        // application context, which isn't associated with any display. Instead, grab the default
        // display, and create a DisplayContext, from which we can use the WindowManager or
        // just get that Display from there.
        //
        // Note: the default display doesn't have to be the one where the app is on, however the
        // getDisplays which returns a Display[] has a length of 1 on Pixel 3.
        //
        // This gets rid of the exception interrupting the onUserLogin() method
        Display defaultDisplay = DisplayManagerCompat.getInstance(context).getDisplay(Display.DEFAULT_DISPLAY);
        Context displayContext = context.createDisplayContext(defaultDisplay);
        return displayContext.getDisplay();
    }

    @SuppressWarnings("deprecation")
    private Display getDisplayPreR(@NonNull WindowManager windowManager) {
        return windowManager.getDefaultDisplay();
    }
Run Code Online (Sandbox Code Playgroud)

或获取实际尺寸:

    private Point getScreenResolution() {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) {
            return null;
        }
        Display display = getDisplay(wm);

        return getSize(display, wm);
    }

    private Point getSize(Display forWhichDisplay, WindowManager windowManager) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return getSizePostR(windowManager);
        } else {
            return getSizePreR(forWhichDisplay);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.R)
    private Point getSizePostR(@NonNull WindowManager windowManager) {
        WindowMetrics currentWindowMetrics = windowManager.getCurrentWindowMetrics();
        Rect bounds = currentWindowMetrics.getBounds();

        // Get the insets, such as titlebar and other decor views
        WindowInsets windowInsets = currentWindowMetrics.getWindowInsets();
        Insets insets = windowInsets.getInsets(WindowInsets.Type.navigationBars());
        // If cutouts exist, get the max of what we already calculated and the system's safe insets
        if (windowInsets.getDisplayCutout() != null) {
            insets = Insets.max(
                    insets,
                    Insets.of(
                            windowInsets.getDisplayCutout().getSafeInsetLeft(),
                            windowInsets.getDisplayCutout().getSafeInsetTop(),
                            windowInsets.getDisplayCutout().getSafeInsetRight(),
                            windowInsets.getDisplayCutout().getSafeInsetBottom()
                    )
            );
        }
        // Calculate the inset widths/heights
        int insetsWidth = insets.right + insets.left;
        int insetsHeight = insets.top + insets.bottom;

        // Get the display width
        int displayWidth = bounds.width() - insetsWidth;
        int displayHeight = bounds.height() - insetsHeight;

        return new Point(displayWidth, displayHeight);
    }

    // This was deprecated in API 30
    @SuppressWarnings("deprecation")
    private Point getSizePreR(Display display) {
        Point size = new Point();
        if (isRealDisplaySizeAvailable()) {
            display.getRealSize(size);
        } else {
            display.getSize(size);
        }

        return size;
    }

    private static boolean isRealDisplaySizeAvailable() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
    }
Run Code Online (Sandbox Code Playgroud)


Jon*_*lon 5

我使用DisplayCompatManager在 android R-Above 上获取宽度和高度,并使用DisplayMatrics在其他 android 版本上获取它。

所以,这是我的代码(+ @Suppress("DEPRECATION") )

private fun screenValue() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

        val defaultDisplay =
            DisplayManagerCompat.getInstance(this).getDisplay(Display.DEFAULT_DISPLAY)
        val displayContext = createDisplayContext(defaultDisplay!!)

        width = displayContext.resources.displayMetrics.widthPixels
        height = displayContext.resources.displayMetrics.heightPixels

        Log.e(tag, "width (ANDOIRD R/ABOVE): $width")
        Log.e(tag, "height (ANDOIRD R/ABOVE) : $height")

    } else {

        val displayMetrics = DisplayMetrics()
        @Suppress("DEPRECATION")
        windowManager.defaultDisplay.getMetrics(displayMetrics)

        height = displayMetrics.heightPixels
        width = displayMetrics.widthPixels

        Log.e(tag, "width (BOTTOM ANDROID R): $width")
        Log.e(tag, "height (BOTTOM ANDROID R) : $height")

    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想在 github 上查看我的要点