最近Flutter推出了WebView预览版,采用原生组件嵌入到Flutter中,今天特地查阅了一下FlutterWebView的实现,然后试着写了一下EditText嵌入到Flutter,然后结果是成功的,但是输入框键盘不能弹出。。。
第一步,创建FlutterEditTextView, 实现接口类:PlatformView, MethodChannel.MethodCallHandler
代码如下:
import android.content.Context
import android.view.View
import android.widget.EditText
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView
class FlutterEditTextView : PlatformView, MethodChannel.MethodCallHandler {
private var editText: EditText
private val methodChannel: MethodChannel
constructor(context: Context?, id: Int, args: Map<String, Any>?, messenger: BinaryMessenger?) {
editText = EditText(context)
editText.setText(
when {
args?.containsKey("text") == true -> args["text"].toString()
else -> ""
}
)
if (args?.containsKey("textColor") == true && args["textColor"] != null)
editText.setTextColor(args["textColor"]!!.toString().toInt())
editText.hint = when {
args?.containsKey("text") == true -> args["text"].toString()
else -> ""
}
if (args?.containsKey("hintTextColor") == true && args["hintTextColor"] != null)
editText.setHintTextColor(args["hintTextColor"]!!.toString().toInt())
methodChannel = MethodChannel(messenger, "plugins.demo.cn/editor_$id")
methodChannel.setMethodCallHandler(this)
}
override fun getView(): View = editText
override fun dispose() {
}
override fun onMethodCall(methodCall: MethodCall?, result: MethodChannel.Result?) {
}
}
第二步,实现Factory类, 继承PlatformViewFactory
class FlutterEditTextViewFactory(private val messenger: BinaryMessenger) :
PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context?, id: Int, args: Any?): PlatformView =
FlutterEditTextView(context, id, args as? Map<String, Any>?, messenger)
}
第三步,实现Plugin类
object FlutterEditTextViewPlugin {
const val ChannelName = "com.mrper.hotpot.core.flutter.plugin.FlutterEditTextViewPlugin"
@JvmStatic
fun registerWith(registrar: Registrar) {
registrar
.platformViewRegistry()
.registerViewFactory(
"plugins.demo.cn/editor", FlutterEditTextViewFactory(registrar.messenger())
)
}
}
第四步,注册插件
val ChannelName = "com.demo.flutter/activity_channel"
if (!pluginRegistry.hasPlugin(FlutterEditTextViewPlugin.ChannelName))
FlutterEditTextViewPlugin.registerWith(pluginRegistry.registrarFor(FlutterEditTextViewPlugin.ChannelName))
第五步,Flutter端实现EditText组件
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
typedef void EditTextCreatedCallback(EditTextController controller);
class EditText extends StatefulWidget {
const EditText({
Key key,
this.text,
this.textColor,
this.hint,
this.hintTextColor,
this.onEditTextCreated,
this.gestureRecognizers,
}) : super(key: key);
final String text;
final int textColor;
final String hint;
final int hintTextColor;
final EditTextCreatedCallback onEditTextCreated;
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
@override
State createState() => _EditTextState();
}
class _EditTextState extends State<EditText> {
@override
Widget build(BuildContext context) {
return AndroidView(
viewType: "plugins.demo.cn/editor",
onPlatformViewCreated: (id) {},
layoutDirection: TextDirection.ltr,
creationParams: _CreationParams.fromWidget(widget).toMap(),
gestureRecognizers: widget.gestureRecognizers,
creationParamsCodec: const StandardMessageCodec(),
);
}
}
class _CreationParams {
_CreationParams({
this.text,
this.textColor,
this.hint,
this.hintTextColor,
});
static _CreationParams fromWidget(EditText widget) {
return _CreationParams(
text: widget.text,
textColor: widget.textColor,
hint: widget.hint,
hintTextColor: widget.hintTextColor);
}
final String text;
final int textColor;
final String hint;
final int hintTextColor;
Map<String, dynamic> toMap() {
return <String, dynamic>{
'text': text,
'textColor': textColor,
'hint': hint,
'hintTextColor': hintTextColor,
};
}
}
class EditTextController {
EditTextController._(int id)
: _channel = MethodChannel('plugins.demo.cn/editor_$id');
final MethodChannel _channel;
}
第六步,Good Job! 你能在你的布局中使用EditText了,但是效果肯定是。。。让你无语的,哈哈,暂时就这样,毕竟还只是个实验性的功能!