{"record":{"id":"79582a25dc433dca","repo":"Tencent/QMUI_Android","slug":"view-is-not-attached-to-activity","errorCode":null,"errorMessage":"View is not attached to Activity","messagePattern":"View is not attached to Activity","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"compose/src/main/java/com/qmuiteam/compose/modal/QMUIModal.kt","lineNumber":107,"sourceCode":"\n    fun doOnShow(listener: Action): QMUIModal\n    fun doOnDismiss(listener: Action): QMUIModal\n    fun removeOnShowAction(listener: Action): QMUIModal\n    fun removeOnDismissAction(listener: Action): QMUIModal\n\n    fun interface Action {\n        fun invoke(modal: QMUIModal)\n    }\n}\n\nfun interface ModalHostProvider {\n    fun provide(view: View): Pair<FrameLayout, OnBackPressedDispatcher>\n}\n\nclass ActivityHostModalProvider : ModalHostProvider {\n    override fun provide(view: View): Pair<FrameLayout, OnBackPressedDispatcher> {\n        val contentLayout =\n            view.rootView.findViewById<FrameLayout>(Window.ID_ANDROID_CONTENT) ?: throw RuntimeException(\"View is not attached to Activity\")\n        val activity = contentLayout.context as? AppCompatActivity ?: throw RuntimeException(\"view's rootView's context is not AppCompatActivity\")\n        return contentLayout to activity.onBackPressedDispatcher\n    }\n}\n\nval DefaultModalHostProvider = ActivityHostModalProvider()\n\nfun View.qmuiModal(\n    mask: Color = DefaultMaskColor,\n    systemCancellable: Boolean = true,\n    maskTouchBehavior: MaskTouchBehavior = MaskTouchBehavior.dismiss,\n    uniqueId: Long = SystemClock.elapsedRealtimeNanos(),\n    modalHostProvider: ModalHostProvider = DefaultModalHostProvider,\n    enter: EnterTransition = fadeIn(tween(), 0f),\n    exit: ExitTransition = fadeOut(tween(), 0f),\n    content: @Composable AnimatedVisibilityScope.(QMUIModal) -> Unit\n): QMUIModal {\n    if (!isAttachedToWindow) {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/Tencent/QMUI_Android/blob/026e7d486677d6593a96689cd590ec3561176717/compose/src/main/java/com/qmuiteam/compose/modal/QMUIModal.kt#L89-L125","documentation":"ActivityHostModalProvider.provide() walks from the given View up to its rootView and looks up the window's android.R.id.content FrameLayout. If that lookup returns null, the view hierarchy is not an Activity window (e.g. the view lives in a Dialog, or was never attached), so a RuntimeException is thrown because there is no Activity content parent to host the modal.","triggerScenarios":"Calling qmuiModal/qmuiStillModal (or qmuiBottomSheet/qmuiDialog/qmuiToast) with a view whose rootView does not contain Window.ID_ANDROID_CONTENT — i.e. the view is attached to a non-Activity window (Dialog, PopupWindow, overlay) or the rootView lacks the content frame.","commonSituations":"Showing a modal from a Dialog or floating window context; view not yet attached so rootView is a temporary parent; using the modal inside a custom presentation or Compose-in-Dialog host.","solutions":["Ensure the view passed to the modal API is attached to a normal Activity window (check view.isAttachedToWindow first).","Pass a view that is a descendant of the Activity's content view, not one hosted in a Dialog/PopupWindow.","Supply a custom ModalHostProvider that resolves the FrameLayout and OnBackPressedDispatcher for your non-standard host.","Defer showing the modal until after the Activity content is laid out (e.g. view.post { })."],"exampleFix":"// before\nmyDialogContentView.qmuiDialog { ... } // throws: not in Activity window\n// after\nrequireNotNull(activity.findViewById<ViewGroup>(android.R.id.content))\nactivity.contentView.qmuiDialog { ... }","handlingStrategy":"validation","validationCode":"fun isHostedInActivity(view: View): Boolean =\n  view.isAttachedToWindow && view.rootView.findViewById<ViewGroup>(android.R.id.content) != null","typeGuard":"fun View.findActivityContent(): FrameLayout? = rootView.findViewById(Window.ID_ANDROID_CONTENT)","tryCatchPattern":"try { view.qmuiDialog { ... } } catch (e: RuntimeException) { Log.e(TAG, \"modal host unavailable\", e) }","preventionTips":["Only trigger modals from views attached to an Activity window","Avoid hosting modal-triggering views inside Dialogs/Popups","Check isAttachedToWindow before calling modal APIs"],"tags":["android","ui","modal","view-attachment"],"backgroundTag":"invalid-state-transition","analyzedSha":"026e7d486677d6593a96689cd590ec3561176717","analyzedAt":"2026-09-06T13:32:24.816Z","contentChangedAt":"2026-09-06T13:32:24.816Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}