How to host an Android Fragment in a Flutter app as a native view when the context is a MutableContextWrapper and needs to be added to the View class Ask Question

0 votes

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

Apr 6, 2023 in Flutter by Ashwini
• 5,430 points
1,666 views

1 answer to this question.

0 votes

It seems that the issue is caused by trying to cast MutableContextWrapper to FragmentActivity, which is not possible.

To solve this issue, you can try to get the actual activity instance from the MutableContextWrapper using the getBaseContext() method, which returns the original context that the MutableContextWrapper is wrapping.

To know more, join our Flutter Training today.

answered Apr 6, 2023 by pooja

Related Questions In Flutter

0 votes
1 answer

How to Deserialize a list of objects from json in flutter Ask Question?

To deserialize a list of objects from ...READ MORE

answered Mar 28, 2023 in Flutter by vishalini
1,532 views
0 votes
1 answer

How to present an empty view in flutter?

In Flutter, you can present an empty ...READ MORE

answered Mar 27, 2023 in Flutter by anonymous
2,553 views
0 votes
1 answer

How to change Android minSdkVersion in Flutter Project?

Yes, you can change the minSdkVersion in ...READ MORE

answered Mar 21, 2023 in Flutter by Tej
7,236 views
+1 vote
1 answer

net: ERR_UNKNOWN_URL_SCHEME in Android Webview codes not working in Kotlin

3 ways to fix the err_unknown_url_scheme error. You ...READ MORE

answered Nov 8, 2022 in Android by Edureka
• 13,620 points
7,942 views
0 votes
1 answer

How can we get the current location in Android?

First you need to define a LocationListener to handle ...READ MORE

answered Sep 25, 2018 in Java by Parth
• 4,630 points
733 views
0 votes
1 answer

Can't find class CognitoUserPoolsSignInProvider: Issue with Sign In integration

CognitoUserPoolsSignInProvider is ditributed as part of aws-android-sdk-auth-userpools library. Please import ...READ MORE

answered Sep 28, 2018 in AWS by Priyaj
• 58,090 points
660 views
0 votes
1 answer
0 votes
1 answer

How can I change the app display name build with Flutter?

Yes, you can change the app display ...READ MORE

answered Mar 21, 2023 in Flutter by venky
1,843 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP