API 30级别中的getSize()已被弃用

13

我使用了getSize()方法来获取屏幕尺寸:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val fragmentActivity = requireActivity()
    ...
    val wm = fragmentActivity.getSystemService(Context.WINDOW_SERVICE) as WindowManager 
    val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        fragmentActivity.display
    } else {
        wm.defaultDisplay 
    }
    val size = Point()
    display?.getSize(size)
    
    // get screen sizes
    val width = size.x
    val height = size.y
    ...
}

但是在API level 30中,方法getSize()被声明为不推荐使用。

获取屏幕尺寸时可以使用什么替代getSize()?

感谢任何评论/答案!

解决方案:

val wm = fragmentActivity.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val width: Int
val height: Int
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    val windowMetrics = wm.currentWindowMetrics
    val windowInsets: WindowInsets = windowMetrics.windowInsets

    val insets = windowInsets.getInsetsIgnoringVisibility(
          WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout())
    val insetsWidth = insets.right + insets.left
    val insetsHeight = insets.top + insets.bottom

    val b = windowMetrics.bounds
    width = b.width() - insetsWidth
    height = b.height() - insetsHeight
} else {
    val size = Point()
    val display = wm.defaultDisplay // deprecated in API 30
    display?.getSize(size) // deprecated in API 30
    width = size.x
    height = size.y
}
3个回答

9
如果您和我一样,只是想获取窗口大小,那么这里有一个兼容版本:
fun WindowManager.currentWindowMetricsPointCompat(): Point {
    return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
        val windowInsets = currentWindowMetrics.windowInsets
        var insets: Insets = windowInsets.getInsets(WindowInsets.Type.navigationBars())
        windowInsets.displayCutout?.run {
            insets = Insets.max(insets, Insets.of(safeInsetLeft, safeInsetTop, safeInsetRight, safeInsetBottom))
        }
        val insetsWidth = insets.right + insets.left
        val insetsHeight = insets.top + insets.bottom
        Point(currentWindowMetrics.bounds.width() - insetsWidth, currentWindowMetrics.bounds.height() - insetsHeight)
    }else{
        Point().apply {
            defaultDisplay.getSize(this)
        }
    }
}

它将处理导航栏的插图和显示裁剪区域,以使两种情况下获得相同的结果。


8
新的Jetpack WindowManager库为新的窗口管理器功能(例如可折叠设备和Chrome OS)提供了一个通用的API界面,适用于旧版和新版平台版本。
dependencies {
    implementation "androidx.window:window:1.0.0-beta02"
}

Jetpack WindowManager提供了两种检索WindowMetrics信息的方式,一种是异步流,另一种是同步方式。

异步WindowMetrics流:

使用WindowInfoRepository#currentWindowMetrics以使库在窗口大小更改时通知您,无论此更改是否触发配置更改。

import androidx.window.layout.WindowInfoRepository
import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository
import androidx.window.layout.WindowMetrics
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.flowWithLifecycle

lifecycleScope.launch(Dispatchers.Main) {
    windowInfoRepository().currentWindowMetrics.flowWithLifecycle(lifecycle)
        .collect { windowMetrics: WindowMetrics ->
           val currentBounds = windowMetrics.bounds // E.g. [0 0 1350 1800]
           val width = currentBounds.width()
           val height = currentBounds.height()
        }
}

同步WindowMetrics:

在编写视图中的代码时,如果异步API难以处理(例如onMeasure或测试期间),请使用WindowMetricsCalculator

import androidx.window.layout.WindowMetricsCalculator
import androidx.window.layout.WindowMetrics

val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
val currentBounds = windowMetrics.bounds // E.g. [0 0 1350 1800]
val width = currentBounds.width()
val height = currentBounds.height()

参考: 解构 WindowManager | Android 开发者 Medium


import androidx.window.WindowManager 似乎不存在。 - moyo
WindowManagerv1.0.0-alpha10中被移除,推荐使用WindowInfoRepositoryWindowMetricsCalculator。我刚刚更新了答案。谢谢。 - David Miguel

3
使用WindowManager#getCurrentWindowMetrics()获取WindowMetrics实例,并改用WindowMetrics#getBounds()。

这是来自Android文档的内容。 [Android文档] {{link1:https://developer.android.com/reference/android/view/Display#getSize(android.graphics.Point)}}

14
不必要的粗鲁回答。 - blimpse

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