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

  1. Defer the call until the view is attached: view.doOnAttach { ... } or view.post { ... }.
  2. Show the modal from an Activity/Fragment lifecycle-safe point (onResume / onViewCreated with attach confirmed).
  3. 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

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


AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06). Data as JSON: /api/errors/68a3a6af9f729d80. Report an issue: GitHub.