I have another API library which things happens inside, and I would like to show a dialog if some case happen and options what to do on them if accept / decline, When the dialog need to shows it crashed, BTW is theres any way to get activity context from compose inorder to allow it shows alert dialog in any other compose function I use with my only single activity app? I've tried AlertDialog.Builder(context) as well and same results,
My minimal example:
@Composable
fun Check(){
val context = LocalContext.current
Button(onClick= {
TestObject.alert(context)
}){
Text("Test")
}
}
object TestObject{
... //things happend there
fun alert(context: Context){
... //things happend there
MaterialAlertDialogBuilder(context)
.setTitle("Hi")
.setMessage("Hello World")
.setNeutralButton("OK", null)
.show()
}
}
update: error stack:
dRuntime: FATAL EXCEPTION: main
Process: com.rayan.alertdialogproblem, PID: 4980
java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:241)
at com.google.android.material.internal.ThemeEnforcement.checkAppCompatTheme(ThemeEnforcement.java:211)
at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:146)
at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:75)
at com.google.android.material.dialog.MaterialDialogs.getDialogBackgroundInsets(MaterialDialogs.java:60)
at com.google.android.material.dialog.MaterialAlertDialogBuilder.<init>(MaterialAlertDialogBuilder.java:117)
at com.google.android.material.dialog.MaterialAlertDialogBuilder.<init>(MaterialAlertDialogBuilder.java:103)
at com.rayan.alertdialogproblem.TestObject.alert(MainActivity.kt:58)
at com.rayan.alertdialogproblem.MainActivityKt$Check$1.invoke(MainActivity.kt:43)
at com.rayan.alertdialogproblem.MainActivityKt$Check$1.invoke(MainActivity.kt:42)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke-k-4lQ0M(Clickable.kt:137)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke(Clickable.kt:137)
at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1$1.invokeSuspend(TapGestureDetector.kt:378)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:398)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:432)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:421)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:329)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:432)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:330)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:343)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:287)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:275)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:151)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:90)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-gBdvCQM(PointerInputEventProcessor.kt:77)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:860)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:502)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1890)
at android.app.Activity.dispatchTouchEvent(Activity.java:4196)
E/AndroidRuntime: at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:460)
at android.view.View.dispatchPointerEvent(View.java:14799)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6347)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6148)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5626)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5814)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5871)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8562)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8513)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8482)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8685)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:259)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loopOnce(Looper.java:161)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
thanks in advance
CodePudding user response:
The error says that the dialog requires a theme. You can provide it with ContextThemeWrapper
, either a custom one declared in res/values/themes
, or a default one, like R.style.Theme_MaterialComponents_Dialog
:
MaterialAlertDialogBuilder(ContextThemeWrapper(context, R.style.Theme_MaterialComponents_Dialog))
More info about custom theming can be found here
CodePudding user response:
You should use the composable AlertDialog https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#alertdialog
@Composable
fun Check(){
val showDialog by remember { mutableStateOf(false) }
if(showDialog) {
AlertDialog(
onDismissRequest = {
showDialog = false
},
)
}
Button(onClick= {
showDialog = true
}){
Text("Test")
}
}
The properties available :
- title : Composable that will be shown at the top of the dialog
- text : Composable that will be shown at the center of the dialog
- buttons : Composable that will be shown at the bottom of the dialog
If you want to know every properties check the link above or use android studio to check the properties.
CodePudding user response:
This is an error in theme... You need to set the theme of the MainActivity.kt in your AndroidManifest.xml file. And, that theme (in the styles.xml) has to have a parent called "Theme.AppCompat"