Tencent/QMUI_Android · error · RuntimeException
View is not attached to window
Error message
View is not attached to window
What it means
qmuiModal checks this View.isAttachedToWindow before resolving the modal host. If the view is not currently attached to a window, showing a modal is impossible (no root view / content parent exists), so a RuntimeException is thrown. Called by qmuiBottomSheet, qmuiDialog, and qmuiToast.
Source
Thrown at compose/src/main/java/com/qmuiteam/compose/modal/QMUIModal.kt:126
val activity = contentLayout.context as? AppCompatActivity ?: throw RuntimeException("view's rootView's context is not AppCompatActivity")
return contentLayout to activity.onBackPressedDispatcher
}
}
val DefaultModalHostProvider = ActivityHostModalProvider()
fun View.qmuiModal(
mask: Color = DefaultMaskColor,
systemCancellable: Boolean = true,
maskTouchBehavior: MaskTouchBehavior = MaskTouchBehavior.dismiss,
uniqueId: Long = SystemClock.elapsedRealtimeNanos(),
modalHostProvider: ModalHostProvider = DefaultModalHostProvider,
enter: EnterTransition = fadeIn(tween(), 0f),
exit: ExitTransition = fadeOut(tween(), 0f),
content: @Composable AnimatedVisibilityScope.(QMUIModal) -> Unit
): QMUIModal {
if (!isAttachedToWindow) {
throw RuntimeException("View is not attached to window")
}
val modalHost = modalHostProvider.provide(this)
val modal = AnimateModalImpl(
modalHost.first,
modalHost.second,
mask,
systemCancellable,
maskTouchBehavior,
enter,
exit,
content
)
val hostView = modalHost.first
handleModelUnique(hostView, modal, uniqueId)
return modal
}
fun View.qmuiStillModal(View on GitHub (pinned to 026e7d4866)
Solutions
- Defer the call until the view is attached: view.doOnAttach { ... } or view.post { ... }.
- Show the modal from an Activity/Fragment lifecycle-safe point (onResume / onViewCreated with attach confirmed).
- Guard with a check before calling and skip/retry if not attached.
Example fix
// before
rootView.qmuiDialog { ... } // throws if called in onCreate
// after
rootView.doOnAttach { it.qmuiDialog { ... } } Defensive patterns
Strategy: validation
Validate before calling
if (!view.isAttachedToWindow) { view.doOnAttach { show() } } else { show() } Type guard
val View.canShowModal: Boolean get() = isAttachedToWindow
Try / catch
try { view.qmuiModal { ... } } catch (e: RuntimeException) { pendingShow = true } Prevention
- Call modal APIs after the view is attached (doOnAttach/onResume)
- Never call from onDestroy or recycled item views
- Queue the show request until attach completes
When it happens
Trigger: Calling qmuiModal/qmuiBottomSheet/qmuiDialog/qmuiToast on a view before it is attached (e.g. in onCreate before the view is in the hierarchy) or after it is detached (after onDestroy/RecyclerView recycling).
Common situations: Showing a dialog in Activity.onCreate() without waiting for attach; calling from a detached RecyclerView item view; showing a toast/dialog after configuration change removed the old view.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- View is not attached to Activity
- view's rootView's context is not AppCompatActivity
- don't call #onEnterAnimationStart() directly
- don't call #onEnterAnimationEnd() directly
- Threshold value should be between 0 and 1.0
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/68a3a6af9f729d80.
Report an issue: GitHub.