You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中展示原生视图并关联Android端XML布局

Flutter 展示原生Android视图/Activity实现方案

核心原理说明

你已有的Android XML布局不需要做任何改造,两种实现场景对应不同的关联方式:

场景1:在Flutter页面内嵌入原生XML布局(无需跳转新页面)

直接将原有Activity的XML布局复用到PlatformView中即可,不需要改动原有布局代码。

第一步:Android端实现逻辑

  1. 创建自定义PlatformView类,关联你的XML布局
class MyNativePlatformView(context: Context, id: Int, args: Map<String, Any>?) : PlatformView {
    private val rootView: View
    override fun getView(): View = rootView

    init {
        // 此处直接加载你原有Activity使用的XML布局,和Activity中的inflate逻辑完全一致
        rootView = LayoutInflater.from(context).inflate(R.layout.your_activity_layout, null)
        // 你原有Activity onCreate方法中的控件初始化、事件监听逻辑可以直接搬到这里
        val titleText = rootView.findViewById<TextView>(R.id.tv_title)
        titleText.text = args?.get("title") as? String ?: "默认标题"
    }

    override fun dispose() {}
}
  1. 创建PlatformView工厂类
class MyNativeViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        val params = args as? Map<String, Any>
        return MyNativePlatformView(context, viewId, params)
    }
}
  1. 在MainActivity中注册PlatformView
class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        // 注册标识要和Flutter端保持一致
        flutterEngine.platformViewsController.registry.registerViewFactory(
            "com.example.native_custom_view",
            MyNativeViewFactory()
        )
    }
}

第二步:Flutter端嵌入原生视图

class NativeEmbedPage extends StatelessWidget {
  const NativeEmbedPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("嵌入原生布局")),
      body: const AndroidView(
        // 和Android端注册的标识完全一致
        viewType: "com.example.native_custom_view",
        // 可选:传递参数到原生端
        creationParams: {"title": "从Flutter传递的参数"},
        creationParamsCodec: StandardMessageCodec(),
      ),
    );
  }
}

场景2:通过Method Channel直接跳转原有Activity(无需改造原有Activity代码)

如果你不想改动已经开发完成的Activity逻辑,直接通过Method Channel唤起跳转即可。

第一步:Android端注册Method Channel监听

class MainActivity : FlutterActivity() {
    private val channelName = "com.example.native_jump_channel"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channelName).setMethodCallHandler { call, result ->
            if (call.method == "openCustomActivity") {
                val intent = Intent(this, YourExistingActivity::class.java)
                // 接收Flutter传递的参数
                intent.putExtra("title", call.argument<String>("title"))
                startActivity(intent)
                result.success("跳转成功")
            } else {
                result.notImplemented()
            }
        }
    }
}

第二步:Flutter端调用触发跳转

import 'package:flutter/services.dart';

class JumpPage extends StatelessWidget {
  JumpPage({super.key});

  static const jumpChannel = MethodChannel('com.example.native_jump_channel');

  Future<void> openNativeActivity() async {
    try {
      await jumpChannel.invokeMethod('openCustomActivity', {"title": "传给原生的参数"});
    } on PlatformException catch (e) {
      print("跳转失败:${e.message}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter主页")),
      body: Center(
        child: ElevatedButton(
          onPressed: openNativeActivity,
          child: const Text("打开原生Activity"),
        ),
      ),
    );
  }
}

如果需要从原生Activity回传数据到Flutter,在原生侧调用MethodChannel的invokeMethod方法回传参数即可。

内容的提问来源于stack exchange,提问作者Umair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:54:06