作者:咕噜噜噜lu | 来源:互联网 | 2023-09-02 19:36
接下来来到Android原生层,在原生通过继承PlatformView然后通过getView方法返回需要渲染的控件。packagedev.flutter.example;impor
接下来来到 Android 原生层,在原生通过继承 PlatformView
然后通过 getView
方法返回需要渲染的控件。
package dev.flutter.example;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.platform.PlatformView;
class NativeView implements PlatformView {
@NonNull private final TextView textView;
NativeView(@NonNull Context context, int id, @Nullable Map creationParams) {
textView = new TextView(context);
textView.setTextSize(72);
textView.setBackgroundColor(Color.rgb(255, 255, 255));
textView.setText("Rendered on a native Android view (id: " + id + ")");
}
@NonNull
@Override
public View getView() {
return textView;
}
@Override
public void dispose() {}
}
之后再继承 PlatformViewFactory
通过 create
方法来加载和初始化 PlatformView
。
package dev.flutter.example;
import android.content.Context;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
import java.util.Map;
class NativeViewFactory extends PlatformViewFactory {
@NonNull private final BinaryMessenger messenger;
@NonNull private final View containerView;
NativeViewFactory(@NonNull BinaryMessenger messenger, @NonNull View containerView) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
this.cOntainerView= containerView;
}
@NonNull
@Override
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
final Map creatiOnParams= (Map) args;
return new NativeView(context, id, creationParams);
}
}
最后在 MainActivity
通过 flutterEngine
的 getPlatformViewsController
去注册 NativeViewFactory
。
package dev.flutter.example;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
flutterEngine
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("hybrid-view-type", new NativeViewFactory(null, null));
}
}
当然,如果需要在 Android 上启用 Hybrid Composition
,还需要在 AndroidManifest.xml
添加如下所示代码来启用配置:
package="dev.flutter.example">
android:name="io.flutter.embedded_views_preview"
android:value="true" />
另外,官方表示 Hybrid composition
在 Android 10 以上的性能表现不错,在 10 以下的版本中,Flutter 界面在屏幕上呈现的速度会变慢,这个开销是因为 Flutter 帧需要与 Android 视图系统同步造成的。
为了缓解此问题,应该避免在 Dart 执行动画时显示原生控件,例如可以使用placeholder 来原生控件的屏幕截图,并在这些动画发生时直接使用这个 placeholder。
要介绍 Hybrid Composition
的实现,就不得不介绍本次新增的一个对象:FlutterImageView
。
FlutterImageView
并不是一般意义上的 ImageView
。
事实上 Hybrid Composition
上混合原生控件所需的图层合成就是通过 FlutterImageView
来实现。FlutterImageView
本身是一个普通的原生 View
, 它通过实现了 RenderSurface
接口从而实现如 FlutterSurfaceView
的部分能力。
在 FlutterImageView
内部主要有 ImageReader
、Image
和 Bitmap
三种类,其中:
ImageReader
可以简单理解为就是能够存储 Image
数据的对象,并且可以提供 Surface
用于绘制接受原生层的 Image
数据。Image
就是包含了 ByteBuffers
的像素数据,它和 ImageReader
一般用在原生的如 Camera
相关的领域。Bitmap
是将 Image
转化为可以绘制的位图,然后在 FlutterImageView
内通过 Canvas
绘制出来。
可以看到 FlutterImageView
可以提供 Surface
,可以读取到 Surface
的 Image
数据,然后通过Bitmap
绘制出来。
而在 FlutterImageView
中提供有 background
和 overlay
两种 SurfaceKind
,其中:
另外还有一点可以看到,在 PlatformViewsController
里有 createAndroidViewForPlatformView
和 createVirtualDisplayForPlatformView
两个方法,这也是 Flutter 官方在提供 Hybrid Composition
的同时也兼容 VirtualDisplay
默认的一种做法。
Hybrid Composition
Dart 层通过 PlatformViewsService
触发原生的 PlatformViewsChannel
的 create
方法,之后发起一个 PlatformViewCreationRequest
就会有 usesHybridComposition
的判断,如果为 ture 后面就是走的 createAndroidViewForPlatformView
。
那么 Hybrid Composition
模式下 FlutterImageView
是如何工作的呢?
首先我们把上面第二小节的例子跑起来,同时打开 Android 手机的布局边界,可以看到屏幕中间出现了一个包含 Re
的白色小方块。通过布局边界可以看到, Re
白色小方块其实是一个原生控件。
学习分享
在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了
很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘
如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。
2021最新上万页的大厂面试真题
七大模块学习资料:如NDK模块开发、Android框架体系架构…
只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
**第三,**到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。
**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](
)**
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。
本文已被腾讯CODING开源托管项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录,自学资源及系列文章持续更新中…
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。
本文已被腾讯CODING开源托管项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录,自学资源及系列文章持续更新中…