Reputation: 2534
I used the getSize() method to get the screen sizes:
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
...
}
But with API level 30 the method getSize() is declared deprecated.
What can be used instead of getSize() for obtain screen sizes?
Thank you for any comment/answer!
Solution:
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
}
Upvotes: 13
Views: 14227
Reputation: 108
"Use
WindowManager#getCurrentWindowMetrics()
to obtain an instance of WindowMetrics and use WindowMetrics#getBounds() instead."
It's from Android documentation. [Android doc] https://developer.android.com/reference/android/view/Display#getSize(android.graphics.Point)
Upvotes: 4
Reputation: 14470
The new Jetpack WindowManager library provides a common API surface for new Window Manager features (e.g. foldable devices and Chrome OS) throughout old and new platform versions.
dependencies {
implementation "androidx.window:window:1.0.0-beta02"
}
Jetpack WindowManager offers two ways to retrieve WindowMetrics information, as an asynchronous stream or synchronously.
Asynchronous WindowMetrics flow:
Use WindowInfoRepository#currentWindowMetrics
to get notified by the library when there’s a window size change, independent of whether this change fires a configuration change.
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()
}
}
lifecycleScope
and flowWithLifecycle()
are part of Jetpack Lifecycle library.Synchronous WindowMetrics:
Use WindowMetricsCalculator when writing code in a view where the asynchronous API can be too hard to deal with (such as onMeasure
or during testing).
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()
Ref: Unbundling the WindowManager | Android Developers Medium
Upvotes: 9
Reputation: 526
If like me, you just want to get the window size, here is a compat version :
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)
}
}
}
it will take care of removing insets of navigation bars and display cutout areas to get the same result in both case
Upvotes: 9