https://kotlinlang.org logo
#compose
Title
# compose
v

vide

10/11/2023, 6:02 PM
I feel like I am going crazy too! I have two previews with different devices sizes and
Resources.getSystem().displayMetrics.widthPixels
gives an inconsistent value inside the same preview. Is there something I should be aware of? Repro and screenshot in 🧵
here's some pseudocode
Copy code
@Preview(device="width=1920,height=1080")
@Composable
fun P1() {
  Resources.getSystem().displayMetrics.widthPixels // value here is 1920
    
    // multiple levels deep:
    Resources.getSystem().displayMetrics.widthPixels // value here is 3840
}

@Preview(device="width=3840,height=2160")
@Composable
fun P2() {
  Resources.getSystem().displayMetrics.widthPixels // value here is 3840
}
@Stylianos Gakis previous thread was related to debugging this phenomenon before I realized what was causing it
Are the previews executing in parallel and
Resources.getSystem()
isn't safe to call..?
Here's a real repro:
Copy code
@Preview(device = "spec:shape=Normal,width=3840,height=2160,unit=px,dpi=480")
@Composable
private fun Test1() = Text("${Resources.getSystem().displayMetrics.widthPixels}", fontSize = 100.sp)


@Preview(device = "spec:shape=Normal,width=5000,height=5000,unit=px,dpi=800")
@Composable
private fun Test2() = Column {
    Text("${Resources.getSystem().displayMetrics.widthPixels}", fontSize = 100.sp)
    Boundary()
}

@Composable
fun Boundary() {
    val a = animateFloatAsState(0f)
    Text("${Resources.getSystem().displayMetrics.widthPixels}", fontSize = 100.sp)
}
comment out the animateFloatAsState(0f) and it won't happen
broken on Android Studio Iguana | 2023.2.1 Canary 7 • works on Android Studio Giraffe | 2022.3.1 Patch 2 were there some changes to the preview rendering system? it feels way snappier on iguana also
a

Alex Vanyo

10/11/2023, 7:00 PM
Resources.getSystem().displayMetrics.widthPixels
is a super suspicious call. What are you trying to use that value for?
v

vide

10/11/2023, 7:10 PM
I have a design system where the base unit is a fixed fraction of the screen width, the codebase currently uses that to try to figure out the available viewport width on initialization time. (I am aware of many reasons not to do that, but this UI is exclusively ran on embedded devices with a known set of hardware so it has not been an issue before 😅)
a

Alex Vanyo

10/11/2023, 8:35 PM
Can you use a method that’s closer to the recommendation of caring about the specific current window size you have using
WindowMetricsCalculator
?
Resources.getSystem
is returning something that isn’t intended to be configured for the current screen: https://developer.android.com/reference/android/content/res/Resources#getSystem()
LocalContext.current.resources.displayMetrics.widthPixels
might work slightly better since it’ll be the resources for your current screen (but again in general this is something to avoid, that doesn’t take into account multi-window mode, changing displays, orientation, etc.)
v

vide

10/12/2023, 3:59 AM
I'm kind of wary of introducing calling
LocalContext.current
for every single size definition from a perf perspective. It would also require adding a composable context to the helper function, meaning no more definitions outside composable contexts.
And I don't think I can add that overhead conditionally to apply only to previews. Still would need to be a composable function invocation which probably does add some overhead on its own? And it would also break definitions outside composables. The definition is currently something like:
Copy code
inline val Int.dpx get(): Dp = (this * dpxToDpMultiplier).dp
where the multiplier is global, set on based the maxWidth constraint available to the app root view at startup time (and set once per preview by a preview wrapper composable)
I created an issue to track this further: https://issuetracker.google.com/issues/304743694