ExposedDropdownMenu expanded crashes the app when navigating to another fragment

611 views Asked by At

I have two ExposedDropdownMenu inside a screen with buttons that trigger navigation to different screens.

Currently, I'm struggling with this crash:

java.lang.IllegalArgumentException: View=androidx.compose.material.internal.PopupLayout{c8ce24f V.E...... ......ID 0,0-960,192 #1020002 android:id/content} not attached to window manager
    at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:544)
    at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:433)
    at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:118)
    at androidx.compose.material.internal.PopupLayout.updatePosition(ExposedDropdownMenuPopup.kt:360)
    at androidx.compose.material.internal.PopupLayout.onGlobalLayout(ExposedDropdownMenuPopup.kt:469)
    at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1061)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2987)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1950)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8186)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1056)
    at android.view.Choreographer.doCallbacks(Choreographer.java:878)
    at android.view.Choreographer.doFrame(Choreographer.java:811)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1041)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7743)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:952)

I already tried to hoist the DropDown state to my ViewModel and collapse it before navigating, but still, the navigation was processed faster than the DropDown being collapsed.

Currently my app is in the middle of Compose migration, so I'm using Fragments to hold Composables and Navigation Component to navigate.

2

There are 2 answers

0
Valentin Konovalov On BEST ANSWER

Use a DropdownMenu instead of an ExposedDropdownMenu.

0
Salam El-Banna On

After hours of researching for a fix for this, I couldn't find any. The bug is internal inside the ExposedDropdownMenu class, and even after update my libraries to the latest compose bom: ('androidx.compose:compose-bom:2023.04.01') this was still happening.

The actual issue is that after navigating away, the fragment is not attached anymore, and the ExposedDropdownMenuBox if was expanded will call for dismiss, and dissmiss will call for an updatePosition, so the ExposedDropdownMenuBox try to update its position in a view that is not attached anymore.

SOLUTION: I found an ugly workaround for this, just when I want to navigate to another screen, I delay the navigation 200ms(The time required for animation to complete). I couldn't find any other workaround for this.

handler = Handler(Looper.getMainLooper())
handler?.postDelayed({
   // Your navigation action here
   findNavController().navigateUp()
}, 200)