简体   繁体   中英

Pass text from MainActivity to child TextView in Kotlin

I haven't worked with Android Studio and Kotlin before, but the task of passing data from Flutter via native came up. I need to pass text from MainActivity where I get text via MethodChannel to AndroidTextView and then pass it to Flutter. I can't figure out how to pass the text, I tried to do it with intent, but it seems I am doing something wrong.

MainActivity

class MainActivity : FlutterActivity() {
    private val androidViewId = "INTEGRATION_ANDROID"
    private val methodChannel = "CALL_METHOD"
    private val intentMessageId = "CALL"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        flutterEngine.platformViewsController.registry.registerViewFactory(androidViewId, AndroidTextViewFactory(flutterEngine.dartExecutor.binaryMessenger, Intent()))

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, methodChannel).setMethodCallHandler {
            call, result ->
            if (call.method == intentMessageId) {
                val intent = Intent()
                intent.putExtra(intentMessageId, call.arguments.toString())
                AndroidTextViewFactory(flutterEngine.dartExecutor.binaryMessenger, intent)
                result.success(call.arguments);
            } else {
                result.notImplemented()
            }
        }
    }
}

AndroidTextView

internal class AndroidTextView(context: Context?, id: Int, creationParams: Map<String?, Any?>?, messenger: BinaryMessenger, data: Intent) : PlatformView {
    private val textView: TextView = TextView(context)

    private val intentMessageId = "CALL"

    override fun getView(): View {
        return textView
    }

    override fun dispose() {}

    init {
        val intent = Intent(context, MainActivity::class.java);
        val text = intent.getStringExtra(intentMessageId);
        textView.textSize = 36f
        textView.text = "$text"
    }
}

AndroidTextViewFactory

class AndroidTextViewFactory(messenger: BinaryMessenger, data: Intent) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {

    private val binaryMessenger: BinaryMessenger = messenger
    private val intent: Intent = data

    override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
        val creationParams = args as Map<String?, Any?>?
        return AndroidTextView(context, viewId, creationParams, binaryMessenger, intent)
    }
}

Intent, usually used as Explicit Intent ,

Explicit Intent , communicates between two activities inside the same application.

And the intent is used like this:

class MainActivity : FlutterActivity() {

   fun openActivityTwo(){
        startActivity(Intent(this@MainActivity,ActivityTwo::class.java))
    }
}

class ActivityTwo : FlutterActivity() {}

And I see that your code is very much like the flutter tutorial: Hosting native Android views in your Flutter app with Platform Views

as the tutorial shows, you don't need the MethodChannel

simply register the android native view in MainActivity


class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        flutterEngine
            .platformViewsController
            .registry
            .registerViewFactory("key", NativeViewFactory())
    }


}

then used in dart


class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: Scaffold(
        body: One(),
      ),
    );
  }
}

class One extends StatefulWidget {
  const One({Key? key}) : super(key: key);

  @override
  State<One> createState() => _OneState();
}

class _OneState extends State<One> {
  @override
  Widget build(BuildContext context) {
    // This is used in the platform side to register the view.
    const String viewType = 'key';
    // Pass parameters to the platform side.
    const Map<String, dynamic> creationParams = <String, dynamic>{};

    return PlatformViewLink(
      viewType: viewType,
      surfaceFactory: (context, controller) {
        return AndroidViewSurface(
          controller: controller as AndroidViewController,
          gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
          hitTestBehavior: PlatformViewHitTestBehavior.opaque,
        );
      },
      onCreatePlatformView: (params) {
        return PlatformViewsService.initSurfaceAndroidView(
          id: params.id,
          viewType: viewType,
          layoutDirection: TextDirection.ltr,
          creationParams: creationParams,
          creationParamsCodec: const StandardMessageCodec(),
          onFocus: () {
            params.onFocusChanged(true);
          },
        )
          ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
          ..create();
      },
    );
  }
}

you can handle the relevant data without method channel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM