Flutter - AndroidView,使用原生组件嵌入Flutter

最近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了,但是效果肯定是。。。让你无语的,哈哈,暂时就这样,毕竟还只是个实验性的功能!

    原文作者:Cosecant
    原文地址: https://www.jianshu.com/p/88cb9ce834ef
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞