前言

本篇文章 中写到的是 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内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Flutter中嵌入Android 原生TextView实例教程的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Flutter中文教程-Cookbook

    Flutter中文网的Cookbook中包含了在编写Flutter应用程序时常见问题及示例。设计基础使用主题共享颜色和字体样式Images显示来自网上的图片用占位符淡入图片使用缓存图Lists创建一个基本list创建一个水平list使用长列表创建不同类型子项的List创建一个gridList处理手势处理点击添加Material触摸水波效果实现滑动关闭导航导航到新页面并返回给新页面传值从新页面返回数据给上一个页面网络从网上获取数据进行认证请求使用WebSockets

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部