Flutter中嵌入Android 原生TextView实例教程

前言

本篇文章 中写到的是 flutter 调用了Android 原生的 TextView 案例

添加原生组件的流程基本上可以描述为:

1 android 端实现原生组件PlatformView提供原生view

2 android 端创建PlatformViewFactory用于生成PlatformView

3 android 端创建FlutterPlugin用于注册原生组件

4 flutter 平台嵌入 原生view

1 创建原生组件

创建在fLutter工程时会生成几个文件夹,lib是放flutter工程代码,android和ios文件夹分别是对应的双平台的原生工程。

在这里直接打开Android工程目录,项目默认生成了GeneratedPluginRegistrant和MainActivity两个文件,GeneratedPluginRegistrant不要动,GeneratedPluginRegistrant是flutter中配制使用其他插件时,程序在编译时自动进行插件注册使用的类。

在MainActivity的包下新建自定义View,Flutter的原生View不能直接继承自View,需要实现提供的PlatformView接口:

public class TestTextView implements PlatformView r{

	private final TextView mTestTextView;

	/**
	 *
	 * @param context
	 * @param messenger
	 * @param id
	 * @param params 初始化时 flutter 传递过来的参数
	 */
	TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
		//创建 TextView
		TextView lTextView = new TextView(context);
		lTextView.setText("Android的原生TextView");
		this.mTestTextView = lTextView;

		//flutter 传递过来的参数
		if (params!=null&&params.containsKey("content")) {
			String myContent = (String) params.get("content");
			lTextView.setText(myContent);
		}
	}

	@Override
	public View getView() {
		return mTestTextView;
	}

	@Override
	public void dispose() {

	}

}

2 创建PlatformViewFactory

import android.content.Context;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;

public class TestViewFactory extends PlatformViewFactory {
	private final BinaryMessenger messenger;
	public TestViewFactory(BinaryMessenger messenger) {
		super(StandardMessageCodec.INSTANCE);
		this.messenger = messenger;
	}

	/**
	 *
	 * @param context
	 * @param id
	 * @param args args是由Flutter传过来的自定义参数
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public PlatformView create(Context context, int id, Object args) {
		//flutter 传递过来的参数
		Map<String, Object> params = (Map<String, Object>) args;
		//创建 TestTextView
		return new TestTextView(context, messenger, id, params);

	}

3 创建Plugin并在ManActivity中注册插件

/**
 * flutter 调用 android 原生view
 *
 */
public class TestFluttertoAndroidTextViewPlugin {
	public static void registerWith(PluginRegistry registry) {
		//防止多次注册
		final String key = TestFluttertoAndroidTextViewPlugin.class.getCanonicalName();
		if (registry.hasPlugin(key)) return;
		//初始化 PluginRegistry
		PluginRegistry.Registrar registrar = registry.registrarFor(key);
		//设置标识
		registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
	}
}

MainActivity 中注册

import android.os.Bundle

import io.flutter.app.FlutterActivity
import io.flutter.plugins.FlutterToAndroidPlugins
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 //flutter 项目工程中默认生成的
 GeneratedPluginRegistrant.registerWith(this)
 //这是我们新创建的插件
 TestFluttertoAndroidTextViewPlugin.registerWith(this)

 }

 override fun onDestroy() {
 super.onDestroy()

 }
}

4 flutter页面中嵌入android 原生Textview

4.1 最简单的调用

//这里设置的 viewType值与 android 中插件注册的标识 一至
//registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
mTextWidget = Container(
 height: 200,
 child: AndroidView(
 	//设置标识
  viewType: "com.flutter_to_native_test_textview",
  ),
 );

@override
 Widget build(BuildContext context) {
 // TODO: implement build
 return Scaffold(
  appBar: appBar,
  //显示的页面
  body: mTextWidget,
 );
 }

4.2 flutter 调用 原生view并传参数

   mTextWidget = Container(
   height: 200,
   child: AndroidView(
    //标识
    viewType: "com.flutter_to_native_test_textview",
    creationParams: {
    "content": "flutter 传入的文本内容",
    },
    //参数的编码方式
    creationParamsCodec: const StandardMessageCodec(),
   ),
   );

android 原生中的接收(只会接收一次)

... ...	

TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
		... ..
		//flutter 传递过来的参数
		if (params!=null&&!params.isEmpty()&&params.containsKey("content")) {
			String myContent = (String) params.get("content");
			lTextView.setText(myContent);
		}

	... ...
	}

4.3 flutter 更新 原生view 中的数据

原生组件初始化的参数并不会随着setState重复赋值,可以通过MethodCall来实现更新数据。

首先让原生view组件实现MethodCallHandler接口:

public class TestTextView implements PlatformView , MethodChannel.MethodCallHandler{

	private final TextView mTestTextView;

	TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {

		... ...

		//com.flutter_to_native_test_view_ 是更新数据的通信标识
		MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id);
		methodChannel.setMethodCallHandler(this);
	}

	... ...

	@Override
	public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {

  //updateText 是flutter 中调用的方法名称,可以随意定义
		if ("updateText".equals(methodCall.method)) {
			String text = (String) methodCall.arguments;
			this.mTestTextView .setText(text);
			//对flutter 的回调
			result.success(null);
		}
	}
}

flutter 中调用 android 原生view

 MethodChannel _channel;
 int viewId=0;
   mTextWidget = Container(
   height: 200,
   child: AndroidView(
    //标识
    viewType: "com.flutter_to_native_test_textview",
    creationParams: {
    "content": "flutter 传入的文本内容",
    },
    //参数的编码方式
    creationParamsCodec: const StandardMessageCodec(),
    //view创建完成时的回调
    onPlatformViewCreated: (id) {
    viewId = id;
    },
   ),
   );

更新数据

//这里设置的标识 MethodChannel('com.flutter_to_native_test_textview_$viewId');
// 与android MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id); 中注册的一至
void clickUpdtae(){
_channel = new MethodChannel('com.flutter_to_native_test_textview_$viewId');
 updateTextView();
}

//这里的标识 updateText
//与android 中接收消息的方法中
//if ("updateText".equals(methodCall.method)) {...} 一至
void updateTextView() async {
 return _channel.invokeMethod('updateText', "更新内容");
 }

通过onPlatformViewCreated回调,监听原始组件成功创建,并能够在回调方法的参数中拿到当前组件的id,这个id是系统随机分配的,然后通过这个分配的id加上我们的组件名称最为前缀创建一个和组件通讯的MethodChannel,拿到channel对象之后就可以通过invokeMethod方法向原生组件发送消息了,这里这里调用的是‘updateText'这个方法,参数是一个String

总结

到此这篇关于Flutter中嵌入Android 原生TextView实例教程的文章就介绍到这了,更多相关Flutter嵌入Android 原生TextView内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Flutter Android端启动白屏问题的解决

    问题描述 Flutter 应用在 Android 端上启动时会有一段很明显的白屏现象,白屏的时长由设备的性能决定,设备性能越差,白屏时间越长. 问题分析 其实启动白屏的问题在Android原生应用上也是一个常见问题,大致是因为从用户点击 Launcher Icon 到应用首页显示之间,Android 系统在完成应用的初始化工作,其流程如下: 在 Flutter Android 端上,白屏的问题会更加严重,因为除了 Android 应用启动耗时外,还增加了 Flutter 初始化耗时. 直到 Fl

  • 解决flutter 错误: 程序包androidx.lifecycle不存在问题

    发生于编译时:错误: 程序包androidx.lifecycle不存在 先贴一段报错log,让你更加准确的匹配问题所在,对症下药,药,切克闹. D:\study\flutter\flutter\.pub-cache\hosted\pub.flutter-io.cn\flutter_plugin_android_lifecycle-1.0.8\android\src\main\java\io\flutter\embedding\engine\plugins\lifecycle\FlutterLif

  • android studio 3.6.1升级后如何处理 flutter问题

    前提条件介绍 1.android-studio-3.6.1 死丢丢 配置了dart 和flutter插件 在 3.5.3时 成功运行过flutter工程 2.flutter 版本 Flutter 1.12.13+hotfix.8 • channel stable • https://github.com/flutter/flutter.git Framework • revision 0b8abb4724 (5 weeks ago) • 2020-02-11 11:44:36 -0800 Eng

  • Flutter下Android Studio配置gradle的方法

    一.失败的经历:手动配置gradle 下载gradle包http://gradle.org/gradle-download/ Mac Finder->Applications/应用程序->Android Studio右键显示包内容.继续打开Contents文件夹,正常情况下会有一个gradle文件夹,将下载解压之后的文件复制到这个文件夹下.如果Contents文件夹下没有gradle文件夹,创建gradle文件夹,继续后面的操作 配置gradle环境路径 打开终端,打开系统环境配置文件vim

  • Android studio 切换flutterSDK之后报错及解决办法(推荐)

    Windows系统上面修改了flutter sdk的环境变量地址之后Android studio上面运行flutter项目就会报错 类似于: Could not read script XXX\flutter.gradle' as it does not exist. 还有这样:flutter:Warning! The 'flutter' tool you are currently running is from a different Flutter repository 解决办法: 1.首

  • Flutter调用Android和iOS原生代码的方法示例

    前言 本文主要给大家介绍了关于Flutter调用Android和iOS原生代码的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 分3个大步骤: 1.在flutter中调用原生方法 2.在Android中实现被调用的方法 3.在iOS中实现被调用的方法 在flutter中调用原生方法 场景,这里你希望调用原生方法告诉你一个bool值,这个值的意义你可以随意定,这里表示的意义是是否是中国用户. 你可以在flutter中设计好要调用的方法名称,这里就叫 isChinese 请

  • Android Studio下Flutter环境搭建图文教程

    一.Flutter介绍 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费.开源的. 二.环境搭建 Flutter 的环境搭建⼗分省⼼,特别对应Android开发者⽽⾔,只是在AndroidStuido上安装 插件,并下载flutterSdk到本地,配置在环境变量即可,其实 中⽂⽹的搭建Futter开发环境 已经很贴⼼详细,从

  • Android Studio 下 Flutter 开发环境搭建,Flutter,Dart 插件安装,Flutter SDK 安装,环境变量配置,开发环境检查

    I . Flutter 学习资料 Flutter 学习资料 : ① 官方文档 : https://flutter.dev/docs ② Flutter Android 开发者文档 : https://flutter.dev/docs/get-started/flutter-for/android-devs ② Flutter 插件库 : https://pub.dev/ II . Flutter 开发环境搭建 Flutter 开发环境搭建 : ① Android Studio : https:/

  • android使用flutter的ListView实现滚动列表的示例代码

    现如今打开一个 App,比如头条.微博,都会有长列表,随着我们不断地滑动,视窗内的内容也会不断地更新.今天就用 Flutter 实现一下这种效果. 这里的表现其实就相当于有一个固定长度的容器,然后超出的内容是不可见的,只有当你向上或向下滑动屏幕时,视窗外看不见的内容才会出现在视窗中.如果在 web 开发时,是需要容器加上样式 overflow: auto; 要想用 Flutter 实现,其实也是很简单的,因为 Flutter 为我们提供了 ListView 组件. ListView 主要有以下几

  • 新版Flutter集成到已有Android项目的实现

    FlutterSDK升级后,我们发现不能按照原来的方式集成到已有Android项目中了,因为没有了Flutter这个类,通过阅读源码我找到了新的使用方式. 一.创建Flutter Module 在已有Android工程中集成flutter,可以使用AndroidStudio的new Flutter Module实现,方便快捷. 找到FlutterModule,一连串的next操作即可 创建完成后我们的项目中会多一个叫做flutter的module 并且在项目的setting.gradle文件中会

随机推荐