In a previous article, I introduced Flutter in a native project.

On this basis, document the introduction of native Views into Flutter. (I suggest reading the article above first.)

The end result is a native project that introduces a Flutter as a View and uses a native View within that Flutter View.

The renderings are as follows:

The whole interface is divided into two parts. The upper part of the Flutter View contains a native ImageView. Here is the native WebView.

start

The first is the layout file for MainActivity, with a FrameLayout used to host Flutter.

<?xml version="1.0" encoding="utf-8"? >
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                             xmlns:app="http://schemas.android.com/apk/res-auto"
                                             xmlns:tools="http://schemas.android.com/tools"
                                             android:layout_width="match_parent"
                                             android:layout_height="match_parent"
                                             android:background="# 000000"
                                             tools:context=".MainActivity">

    <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintHeight_percent="0.5"
            app:layout_constraintTop_toTopOf="parent"></FrameLayout>

    <WebView
            android:id="@+id/web"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/content"/>

</android.support.constraint.ConstraintLayout>
Copy the code

The Flutter is loaded as a View.

class MainActivity : AppCompatActivity() {

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableSlowWholeDocumentDraw()
        setContentView(R.layout.activity_main)
        val flutterView = Flutter.createView(this@MainActivity,lifecycle,"route1")
        ViewRegistrant().registerWith(flutterView.pluginRegistry)
        val layout = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
        content.addView(flutterView, layout)
        initWebView()
    }
    @SuppressLint("SetJavaScriptEnabled")
    private fun initWebView() {
        var webSettings = web.settings
        webSettings.javaScriptEnabled = true
        webSettings.setSupportZoom(false)
        web.requestFocusFromTouch()
        web.isVerticalScrollBarEnabled = false
        web.isHorizontalScrollBarEnabled = false
        web.loadUrl("https://www.baidu.com")}}Copy the code

Create a flutterView with val flutterView = Flutter. CreateView (this@MainActivity,lifecycle,”route1″) and Add it to the layout. Route1 is passed into a Flutter.

The first step

Inheriting PlatformViewFactory in its create() method returns a native View to be used in Flutter.

So here I’m returning an ImageView

class NativeImageView(createArgsCodec: MessageCodec<Any>) : PlatformViewFactory(createArgsCodec) { override fun create(context: Context, i: Int, o: Any?) : PlatformView { var imageView = ImageView(context) imageView.layoutParams = ViewGroup.LayoutParams(100, 100) imageView.background = context.resources.getDrawable(R.mipmap.ic_launcher)return object : PlatformView {
            override fun getView(): View {
                return imageView
            }
            override fun dispose() {}}}}Copy the code

The second step

Write a bridge and pass in the View.

class ViewRegistrant : PluginRegistry.PluginRegistrantCallback {
    override fun registerWith(registry: PluginRegistry) {
        val key = ViewRegistrant::class.java.canonicalName
        if (registry.hasPlugin(key)) return
        val registrar = registry.registrarFor(key)
        registrar.platformViewRegistry().registerViewFactory("imageView", NativeImageView(StandardMessageCodec()))
    }
}
Copy the code

The imageView here is going to be used in Flutter.

The third step

Load the bridge and bind it to the FlutterView we’ve created.

ViewRegistrant().registerWith(flutterView.pluginRegistry)

The last

Reference to Flutter.

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: Container(
        color: Color(0xff0000ff),
        child: SizedBox(
          width: size,
          height: size,
          child: AndroidView(
            viewType: 'imageView',
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _changeSize,
        child: new Icon(Icons.add),
      ),
    );
Copy the code

Note: This method requires Android API 20 or above,