I need to host an embedded native view into my Flutter app,
I have an Android Fragment and me trying to add it to the View class that registered in FlutterEngine
but Fragments need to be added:
(context as FragmentActivity).supportFragmentManager
And that does not work due to the existing context is MutableContextWrapper
Any help, please?
MainActivity:
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
flutterEngine
.platformViewsController
.registry
.registerViewFactory("EmbeddedNavigationView.kt", EmbeddedNavigationFactory(mapOf("text" to "hello!")))
}
}
EmbeddedNavigationView:
class EmbeddedNavigationView(context: Context, val viewParams: Map<String, Any>) : View(context), PlatformView {
private lateinit var fragmentMap: Fragment
private val fragment: Fragment = FlutterFragment.createDefault()
init {
initObjects()
initSubView()
}
private fun initObjects() {
fragmentMap = MapFragment()
}
private fun initSubView() {
addFragment(fragmentMap)
}
private fun addFragment(fragment: Fragment) {
// thow error due to MutableContextWrapper is not a FragmentActivity
val fragmentManager = (context as FragmentActivity).supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.add(R.id.fragment_map, fragment)
transaction.commit()
}
private fun removeFragment(fragment: Fragment) {
val fragmentManager = (context as FragmentActivity).supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.remove(fragment)
transaction.commit()
}
override fun onDraw(canvas: Canvas) {
// Draw the view's content
super.onDraw(canvas)
}
override fun onDetachedFromWindow() {
// Remove the fragment when the view is detached
fragmentMap?.let {
(context as AppCompatActivity).supportFragmentManager.beginTransaction().remove(it).commit()
}
super.onDetachedFromWindow()
}
class MyFragment : Fragment() {
// Fragment code here
}
override fun getView(): View? {
return this
TODO("Not yet implemented")
}
override fun dispose() {
// impl dispose
TODO("Not yet implemented")
}
}
EmbeddedNavigationFactory:
class EmbeddedNavigationFactory(private val createParams: Map<String, Any>?) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
val viewParams = createParams ?: args as? Map<String, Any> ?: mapOf()
return EmbeddedNavigationView(context, viewParams)
}
}
MapFragment:
class MapFragment : androidx.fragment.app.Fragment() { ... }
Logs:
Launching lib/main.dart on 2201117TG in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app-debug.apk...
Debug service listening on ws://127.0.0.1:50805/JtPxjixFiC4=/ws
Syncing files to device 2201117TG...
E/MethodChannel#flutter/platform_views(15059): Failed to handle method call
E/MethodChannel#flutter/platform_views(15059): java.lang.ClassCastException: android.content.MutableContextWrapper cannot be cast to androidx.fragment.app.FragmentActivity
E/MethodChannel#flutter/platform_views(15059): at com.example.mapbox_android_update.EmbeddedNavigationView.addFragment(EmbeddedNavigationView.kt:29)
E/MethodChannel#flutter/platform_views(15059): at com.example.mapbox_android_update.EmbeddedNavigationView.initSubView(EmbeddedNavigationView.kt:26)
E/MethodChannel#flutter/platform_views(15059): at com.example.mapbox_android_update.EmbeddedNavigationView.<init>(EmbeddedNavigationView.kt:20)
E/MethodChannel#flutter/platform_views(15059): at com.example.mapbox_android_update.EmbeddedNavigationFactory.create(EmbeddedNavigationFactory.kt:19)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.plugin.platform.PlatformViewsController$1.createPlatformView(PlatformViewsController.java:503)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.plugin.platform.PlatformViewsController$1.createForTextureLayer(PlatformViewsController.java:191)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.create(PlatformViewsChannel.java:128)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall(PlatformViewsChannel.java:55)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
E/MethodChannel#flutter/platform_views(15059): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#flutter/platform_views(15059): at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#flutter/platform_views(15059): at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#flutter/platform_views(15059): at android.os.Looper.loopOnce(Looper.java:210)
E/MethodChannel#flutter/platform_views(15059): at android.os.Looper.loop(Looper.java:299)
E/MethodChannel#flutter/platform_views(15059): at android.app.ActivityThread.main(ActivityThread.java:8309)
E/MethodChannel#flutter/platform_views(15059): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#flutter/platform_views(15059): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
E/MethodChannel#flutter/platform_views(15059): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1038)
E/flutter (15059): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(error, android.content.MutableContextWrapper cannot be cast to androidx.fragment.app.FragmentActivity, null, java.lang.ClassCastException: android.content.MutableContextWrapper cannot be cast to androidx.fragment.app.FragmentActivity
E/flutter (15059): at com.example.mapbox_android_update.EmbeddedNavigationView.addFragment(EmbeddedNavigationView.kt:29)
E/flutter (15059): at com.example.mapbox_android_update.EmbeddedNavigationView.initSubView(EmbeddedNavigationView.kt:26)
E/flutter (15059): at com.example.mapbox_android_update.EmbeddedNavigationView.<init>(EmbeddedNavigationView.kt:20)
E/flutter (15059): at com.example.mapbox_android_update.EmbeddedNavigationFactory.create(EmbeddedNavigationFactory.kt:19)
E/flutter (15059): at io.flutter.plugin.platform.PlatformViewsController$1.createPlatformView(PlatformViewsController.java:503)
E/flutter (15059): at io.flutter.plugin.platform.PlatformViewsController$1.createForTextureLayer(PlatformViewsController.java:191)
E/flutter (15059): at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.create(PlatformViewsChannel.java:128)
E/flutter (15059): at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall(PlatformViewsChannel.java:55)
E/flutter (15059): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
E/flutter (15059): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/flutter (15059): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
E/flutter (15059): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/flutter (15059): at android.os.Handler.handleCallback(Handler.java:938)
E/flutter (15059): at android.os.Handler.dispatchMessage(Handler.java:99)
E/flutter (15059): at android.os.Looper.loopOnce(Looper.java:210)
E/flutter (15059): at android.os.Looper.loop(Looper.java:299)
E/flutter (15059): at android.app.ActivityThread.main(ActivityThread.java:8309)
E/flutter (15059): at java.lang.reflect.Method.invoke(Native Method)
E/flutter (15059): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
E/flutter (15059): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1038)
E/flutter (15059): )
E/flutter (15059): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:653:7)
E/flutter (15059): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:315:18)
E/flutter (15059): <asynchronous suspension>
E/flutter (15059): #2 TextureAndroidViewController._sendCreateMessage (package:flutter/src/services/platform_views.dart:1141:28)
E/flutter (15059): <asynchronous suspension>
E/flutter (15059): #3 AndroidViewController.create (package:flutter/src/services/platform_views.dart:801:5)
E/flutter (15059): <asynchronous suspension>
E/flutter (15059): #4 AndroidViewController.setSize (package:flutter/src/services/platform_views.dart:828:7)
E/flutter (15059): <asynchronous suspension>
E/flutter (15059): #5 RenderAndroidView._sizePlatformView (package:flutter/src/rendering/platform_view.dart:182:29)
E/flutter (15059): <asynchronous suspension>
E/flutter (15059):
E/_android_updat(15059): open libmigui.so failed! dlopen - dlopen failed: library "libmigui.so" not found
D/DecorView[](15059): onWindowFocusChanged hasWindowFocus true
adding this android native fragment to flutter app