返回

技术创作:让 Flutter 巧用外部纹理,点亮视觉盛宴

Android

万万没想到——Flutter 这样玩转外部纹理

回溯到 13 年,多路视频通话的兴起带来了端上渲染的巨大性能瓶颈。究其原因,在于每一路视频画面都必须频繁执行高速上屏(PresentRenderBuffer 或 SwapBuffer)操作,即把渲染缓冲区的渲染结果呈现到屏幕上,这会消耗大量 CPU 和 GPU 资源。彼时的解决方案是将绘制和上屏解耦,只在画面内容发生变化时才执行上屏操作。

时过境迁,如今的 Flutter 框架为我们提供了更优雅的方式来应对类似的渲染性能挑战——外部纹理。

外部纹理的奥秘

外部纹理,顾名思义,就是 Flutter 应用程序之外的纹理,它允许我们直接使用原生平台提供的纹理,而不是通过 Flutter 的渲染引擎进行渲染。这为我们带来了以下优势:

  • 提升渲染性能: 外部纹理绕过了 Flutter 的渲染管道,大幅减少了 CPU 和 GPU 的消耗,从而提高了渲染效率。
  • 拓展视觉效果: 外部纹理支持各种复杂的视觉效果,例如视频播放、相机预览和高级 3D 图形,这些效果在 Flutter 的默认渲染引擎中可能难以实现。
  • 跨平台兼容性: 外部纹理在 Android 和 iOS 平台上都得到支持,确保了应用程序在不同设备上的视觉一致性。

使用外部纹理

在 Flutter 中使用外部纹理需要遵循以下步骤:

  1. 创建纹理绑定: 创建一个 TextureBinding 对象,它将作为外部纹理的桥梁。
  2. 设置纹理 ID: 使用 PlatformViewRegistry.instance.getNextTextureId() 为外部纹理生成一个唯一的 ID。
  3. 创建纹理注册器: 创建一个 TextureRegistrar 对象,它将负责管理外部纹理的生命周期和事件处理。
  4. 注册外部纹理: 将外部纹理注册到 TextureRegistrar 上,关联纹理 ID 和 TextureBinding 对象。
  5. 使用纹理: 在 Flutter 组件中使用 Texture widget,指定外部纹理的纹理 ID。

案例分析:视频播放

让我们通过一个实际案例来深入了解外部纹理的应用。视频播放是移动应用程序中常见的场景,但原生视频播放器通常无法与 Flutter 应用程序无缝集成。使用外部纹理,我们可以轻松解决这个问题:

import 'package:flutter/material.dart';
import 'dart:ui';

class VideoPlayer extends StatefulWidget {
  @override
  _VideoPlayerState createState() => _VideoPlayerState();
}

class _VideoPlayerState extends State<VideoPlayer> {
  late Texture texture;
  late TextureBinding textureBinding;
  late VideoPlayerController videoPlayerController;

  @override
  void initState() {
    super.initState();
    // 创建纹理绑定
    textureBinding = TextureBinding();
    // 获取纹理 ID
    int textureId = PlatformViewRegistry.instance.getNextTextureId();
    // 创建纹理注册器
    TextureRegistrar textureRegistrar = TextureRegistrar();
    // 注册外部纹理
    textureRegistrar.registerTexture(textureId, textureBinding);
    // 创建视频播放器控制器
    videoPlayerController = VideoPlayerController.network('path/to/video.mp4');
    // 初始化视频播放器控制器
    videoPlayerController.initialize().then((_) {
      // 将外部纹理与视频播放器控制器关联
      textureBinding.setVideoTexture(videoPlayerController.textureId);
      // 播放视频
      videoPlayerController.play();
    });
  }

  @override
  void dispose() {
    // 释放资源
    videoPlayerController.dispose();
    textureRegistrar.dispose();
    textureBinding.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Texture(textureId: textureId);
  }
}

通过这段代码,我们成功地将原生视频播放器集成了 Flutter 应用程序,并充分利用了外部纹理的优势。

结语

外部纹理是 Flutter 中一项功能强大的工具,它为提升渲染性能、拓展视觉效果和跨平台兼容性提供了无限可能。掌握外部纹理的使用技巧,将使您能够构建出流畅、美观且功能丰富的移动应用程序。如果您尚未尝试使用外部纹理,强烈建议您在下一个 Flutter 项目中一探究竟。