Flutter快速上手,入门教程

目录

一、参考文档

二、准备工作

下载Flutter SDK:

配置环境

解决环境报错 zsh:command not found:flutter

执行【flutter doctor】测试效果

安装Xcode IOS环境

需要安装brew,通过brew安装CocoaPods.

复制命令行,打开终端

分别执行下面命令

如图所示

三、创建Flutter IOS项目

Mac 创建Flutter IOS项目

通过 sudo chmod -R 777 * 修改一下文件权限

Xcode 打开Flutter项目 

Android Studio创建Flutter项目

​Flutter目录层级介绍

依赖库/图片的引用 

pub包管理系统:

 使用第三库,在官网找到对应的库

 复制地方库的引用方式

四、Flutter简单应用

1.主题设置

1.1 定义主题数据

1.2 状态管理(以 Provider 为例)

1.3 在 MaterialApp 中应用主题

1.4 创建主题切换界面

2. 国际化

2.1 添加依赖

2.2 配置支持的语言

2.3 创建多语言资源文件

定义基础接口

实现英语资源

实现中文资源

创建本地化代理

在 UI 中使用本地化字符串

3. 相机相册调用

3.1 添加依赖

3.2 配置权限

iOS

Android

3.3 实现相机和相册功能

3.4 高级功能

拍摄视频

多选图片

五、Flutter 调用原生代码

基本原理

实现步骤

在 Flutter 端创建通道

在 Android 端实现(Kotlin)

在 iOS 端实现(Swift)

六、Flutter 打包工具


一、参考文档

API文档

链接

Flutter地址

https://docs.flutter.dev/

Homebrew地址

https://brew.sh

pub包管理系统

The official repository for Dart and Flutter packages.

Material Design官方Icons图标

https://fonts.google.com/icons

二、准备工作

  1. 升级Macos系统为最新系统

  2. 安装最新的Xcode

  3. 电脑上面需要安装brew https://brew.sh/

  4. 安装chrome浏览器(开发web用)

下载Flutter SDK:

FlutterSDK下载地址: https://docs.flutter.dev/get-started/install

常用编译软件:

  • Visual Studio Code with the Flutter extension for VS Code.

  • Android Studio with the Flutter plugin for IntelliJ.

  • IntelliJ IDEA with both the Flutter plugin for IntelliJ and the Android plugin for IntelliJ.

下载zip并解压到本地文件中

配置环境

  1. 打开命令行,执行【open ~/.bash_profile 】

  2. 把刚解压好的FlutterSDK文件地址进行配置,把内容粘贴到.bash_profile文件

export PATH="$PATH:/home/yourusername/flutter/bin"
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

      3.  执行【source ~/.bash_profile 】,将.bash_profile文件生效

      4. 执行【flutter doctor】测试效果。

注意哈:这样配置,如果你只有(bash_profile,没有zshrc文件)。
需要每次打开终端输入一下 source ~/.bash_profile 命令,再使用flutter命令。不然会报错。
zsh:command not found:flutter

像下面图片效果:

解决环境报错 zsh:command not found:flutter

1、执行:【open ~/.zshrc 】

2、如果 提示文件不存在,则执行:【vim ~/.zshrc 】新建一个新文件。

 vim ~/.zshrc

再使用source命令重新加载一下:【source ~/.zshrc】,下次再编辑这个文件就可以直接执行:【open ~/.zshrc】

source ~/.zshrc 

执行【flutter doctor】测试效果

这个时候试试关闭终端再输入flutter doctor,此时Flutter SDK配置完成,按照下面提示进行安装操作(下载Android SDK、Xcode、CocoaPods)。

安装Xcode IOS环境

需要安装brew,通过brew安装CocoaPods.

Homebrew官网: https://brew.sh/

复制命令行,打开终端

分别执行下面命令

brew install cocoapods.pod setupsudo xcode-select --switch /Applications/xcode.app/contents/Developersudo xcodebuild -runFirstLaunch

如图所示

brew doctor

三、创建Flutter IOS项目

Mac 创建Flutter IOS项目

sudo flutter create flutterdemo sudo chmod -R 777 flutterdemo //修改一下文件权限 可读。可写 

通过 sudo chmod -R 777 * 修改一下文件权限

Xcode 打开Flutter项目 

flutter run
flutter -d all
flutter -d chrome

Android Studio创建Flutter项目

​Flutter目录层级介绍

依赖库/图片的引用 

pub包管理系统:

官网地址:https://pub.dev/

 使用第三库,在官网找到对应的库

 复制地方库的引用方式

四、Flutter简单应用

1.主题设置

在 Flutter 项目里,实现主题切换功能需要结合状态管理和 Flutter 的主题系统。下面为你介绍实现主题切换的具体步骤:

1.1 定义主题数据

要先创建亮、暗两种主题,并且设置好各自的颜色和样式。

import 'package:flutter/material.dart';class AppThemes {static final lightTheme = ThemeData(brightness: Brightness.light,primaryColor: Colors.blue,scaffoldBackgroundColor: Colors.white,// 其他主题属性...);static final darkTheme = ThemeData(brightness: Brightness.dark,primaryColor: Colors.blue,scaffoldBackgroundColor: Colors.black,// 其他主题属性...);
}

1.2 状态管理(以 Provider 为例)

接着创建一个主题状态管理类,以此来保存和更新当前使用的主题。

import 'package:flutter/material.dart';class ThemeProvider with ChangeNotifier {ThemeMode _themeMode = ThemeMode.system;ThemeMode get themeMode => _themeMode;void toggleTheme(bool isDark) {_themeMode = isDark ? ThemeMode.dark : ThemeMode.light;notifyListeners();}void setSystemTheme() {_themeMode = ThemeMode.system;notifyListeners();}
}

1.3 在 MaterialApp 中应用主题

然后在应用的根 Widget 里配置主题,并监听主题变化。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';void main() {runApp(ChangeNotifierProvider(create: (context) => ThemeProvider(),child: const MyApp(),),);
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Consumer<ThemeProvider>(builder: (context, themeProvider, child) {return MaterialApp(title: 'Flutter Theme Demo',theme: AppThemes.lightTheme,darkTheme: AppThemes.darkTheme,themeMode: themeProvider.themeMode,home: const HomePage(),);},);}
}

1.4 创建主题切换界面

最后添加一个用于切换主题的 UI 组件,像开关或按钮。

class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {final themeProvider = Provider.of<ThemeProvider>(context);final isDark = themeProvider.themeMode == ThemeMode.dark;return Scaffold(appBar: AppBar(title: const Text('主题切换示例'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const Text('切换主题'),Switch(value: isDark,onChanged: (value) {themeProvider.toggleTheme(value);},),],),),);}
}

2. 国际化

在 Flutter 项目中设置国际化需要配置多语言资源并确保应用能根据系统语言自动切换。以下是实现步骤:

2.1 添加依赖

pubspec.yaml中添加flutter_localizationsintl插件:

dependencies:flutter:sdk: flutterflutter_localizations:sdk: flutterintl: ^0.18.1  # 最新版本

2.2 配置支持的语言

MaterialApp中指定支持的语言列表和本地化代理:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter 国际化示例',// 支持的语言列表supportedLocales: [Locale('en', 'US'), // 英语Locale('zh', 'CN'), // 中文// 添加更多语言...],// 本地化代理localizationsDelegates: [AppLocalizations.delegate, // 自定义代理GlobalMaterialLocalizations.delegate, // Material组件本地化GlobalWidgetsLocalizations.delegate, // 小部件库本地化GlobalCupertinoLocalizations.delegate, // Cupertino组件本地化],// 根据系统语言自动选择localelocaleResolutionCallback: (locale, supportedLocales) {for (var supportedLocale in supportedLocales) {if (supportedLocale.languageCode == locale?.languageCode) {return supportedLocale;}}return supportedLocales.first; // 默认返回第一个支持的语言},home: const HomePage(),);}
}

2.3 创建多语言资源文件

创建一个抽象类定义所有翻译键,并为每种语言创建实现类:

定义基础接口
// lib/l10n/app_localizations.dart
import 'package:flutter/material.dart';abstract class AppLocalizations {static AppLocalizations of(BuildContext context) {return Localizations.of<AppLocalizations>(context, AppLocalizations)!;}static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();// 定义翻译键String get appTitle;String greeting(String name);// 添加更多翻译...
}
实现英语资源
// lib/l10n/app_localizations_en.dart
class AppLocalizationsEn extends AppLocalizations {@overrideString get appTitle => 'Flutter Internationalization';@overrideString greeting(String name) => 'Hello, $name!';
}
实现中文资源
// lib/l10n/app_localizations_zh.dart
class AppLocalizationsZh extends AppLocalizations {@overrideString get appTitle => 'Flutter 国际化';@overrideString greeting(String name) => '你好,$name!';
}
创建本地化代理
// lib/l10n/app_localizations.dart (继续)
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {const _AppLocalizationsDelegate();@overridebool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);@overrideFuture<AppLocalizations> load(Locale locale) async {switch (locale.languageCode) {case 'en':return AppLocalizationsEn();case 'zh':return AppLocalizationsZh();default:return AppLocalizationsEn(); // 默认使用英语}}@overridebool shouldReload(_AppLocalizationsDelegate old) => false;
}

在 UI 中使用本地化字符串

// lib/home_page.dart
import 'package:flutter/material.dart';class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {final localizations = AppLocalizations.of(context);return Scaffold(appBar: AppBar(title: Text(localizations.appTitle),),body: Center(child: Text(localizations.greeting('World')),),);}
}

3. 相机相册调用

在 Flutter 中调用相机和相册功能,需要使用image_picker插件。以下是完整实现步骤:

3.1 添加依赖

pubspec.yaml中添加依赖:

dependencies:flutter:sdk: flutterimage_picker: ^1.0.2  # 最新版本

然后执行flutter pub get安装。

3.2 配置权限

iOS

ios/Runner/Info.plist中添加:

<key>NSCameraUsageDescription</key>
<string>应用需要访问相机来拍摄照片</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>应用需要访问相册来选择照片</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>应用需要保存照片到相册</string>
Android

android/app/src/main/AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 10及以下需要 -->

3.3 实现相机和相册功能

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';class CameraGalleryExample extends StatefulWidget {@override_CameraGalleryExampleState createState() => _CameraGalleryExampleState();
}class _CameraGalleryExampleState extends State<CameraGalleryExample> {final ImagePicker _picker = ImagePicker();XFile? _pickedImage;// 从相机拍摄照片Future<void> _takePhoto() async {try {final XFile? photo = await _picker.pickImage(source: ImageSource.camera);if (photo != null) {setState(() {_pickedImage = photo;});}} catch (e) {print('Error taking photo: $e');// 显示错误提示ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('拍照失败: $e')),);}}// 从相册选择照片Future<void> _selectFromGallery() async {try {final XFile? image = await _picker.pickImage(source: ImageSource.gallery);if (image != null) {setState(() {_pickedImage = image;});}} catch (e) {print('Error selecting image: $e');// 显示错误提示ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('选择图片失败: $e')),);}}
}

3.4 高级功能

拍摄视频
Future<void> _recordVideo() async {final XFile? video = await _picker.pickVideo(source: ImageSource.camera);if (video != null) {// 处理视频}
}
多选图片
Future<void> _selectMultipleImages() async {final List<XFile>? images = await _picker.pickMultiImage();if (images != null && images.isNotEmpty) {// 处理多张图片}
}

五、Flutter 调用原生代码

在 Flutter 中调用原生代码(如 Android 的 Java/Kotlin 或 iOS 的 Swift/Objective-C)需要使用 平台通道(Platform Channel)。以下是主要实现方式:

基本原理

MethodChannel 是 Flutter 与原生平台(Android、iOS)之间进行通信的一种机制,属于 Flutter 提供的三种通信通道之一(另外两种是 BasicMessageChannel 和 EventChannel)。它允许 Flutter 代码调用原生代码的方法,也允许原生代码调用 Flutter 代码的方法,实现双向通信。

实现步骤

在 Flutter 端创建通道

import 'package:flutter/services.dart';class DeviceInfo {static const MethodChannel _channel = MethodChannel('com.example.device_info');// 获取设备信息static Future<Map<String, dynamic>> getInfo() async {try {final Map<dynamic, dynamic> result = await _channel.invokeMethod('getDeviceInfo');return Map<String, dynamic>.from(result);} on PlatformException catch (e) {throw Exception('Failed to get device info: ${e.message}');}}Future<void> _fetchDeviceInfo() async {try {final info = await DeviceInfo.getInfo();setState(() {_deviceInfo = info;});} catch (e) {print('Error: $e');}}
}

在 Android 端实现(Kotlin)

package com.example.device_infoimport android.os.Build
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Resultclass DeviceInfoPlugin : FlutterPlugin, MethodCallHandler {private lateinit var channel: MethodChanneloverride fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.example.device_info")channel.setMethodCallHandler(this)}override fun onMethodCall(call: MethodCall, result: Result) {if (call.method == "getDeviceInfo") {val deviceInfo = mutableMapOf<String, Any>()// 添加设备信息deviceInfo["model"] = Build.MODELdeviceInfo["brand"] = Build.BRANDdeviceInfo["device"] = Build.DEVICEdeviceInfo["androidVersion"] = Build.VERSION.RELEASEdeviceInfo["sdkInt"] = Build.VERSION.SDK_INTresult.success(deviceInfo)} else {result.notImplemented()}}override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {channel.setMethodCallHandler(null)}
}package com.example.my_appimport io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import com.example.device_info.DeviceInfoPluginclass MainActivity : FlutterActivity() {override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)// 注册插件flutterEngine.plugins.add(DeviceInfoPlugin())}
}

在 iOS 端实现(Swift)

import Flutter
import UIKitpublic class DeviceInfoPlugin: NSObject, FlutterPlugin {public static func register(with registrar: FlutterPluginRegistrar) {let channel = FlutterMethodChannel(name: "com.example.device_info",binaryMessenger: registrar.messenger())let instance = DeviceInfoPlugin()registrar.addMethodCallDelegate(instance, channel: channel)}public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {if call.method == "getDeviceInfo" {let device = UIDevice.currentlet info = ["model": device.model,"systemName": device.systemName,"systemVersion": device.systemVersion,"localizedModel": device.localizedModel,"name": device.name]result(info)} else {result(FlutterMethodNotImplemented)}}
}import UIKit
import Flutter@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// 注册插件GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

六、Flutter 打包工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八股文——JVM

1. JVM组成 1.1 JVM由哪些部分组成&#xff1f;运行流程&#xff1f; Java Virtual Machine&#xff1a;Java 虚拟机&#xff0c;Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09;好处&#xff1a;一次编写&#xff0c;到处运行&#xff1b;自动内存管理…

在Pnetlab6上绕过TPM、安全启动和 RAM 检查安装windows 11笔记

笔者本次安装的windows11的镜像为: zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso 1、创建镜像目录并上传iso文件 mkdir /opt/unetlab/addons/qemu/win-win11x64-2024-LTSC //目录名称务必按照官方文档格式,否则无法识别 目录创建完成后,将.iso格式镜像上…

PCL点云库入门(第18讲)——PCL库点云特征之3DSC特征描述3D shape context descriptor

一、3DSC&#xff08;3D Shape Context&#xff09;特征算法原理 1. 背景 3DSC 是一种描述三维点云局部形状的特征描述子&#xff0c;受二维 Shape Context 的启发。它用于捕捉点云某一点局部的几何分布信息&#xff0c;对点云配准、识别等任务非常有效。 2. 基本思想 3DSC…

SpringBoot+Mysql校园跑腿服务平台系统源码

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

分库分表的取舍

文章目录 大数据量下采用**水平分表**的缺点**1. 跨表查询复杂性与性能下降****2. 数据分布不均衡****3. 分布式事务与一致性问题****4. 扩展性受限****5. 查询条件限制与索引管理复杂****6. 数据迁移与维护成本高****7. 业务逻辑复杂度增加****总结** shardingJdbc分片策略**1…

Vue3解决“找不到模块@/components/xxx.vue或其相应的类型声明ts文件(2307)”

问题 1&#xff1a;如果没有这个env.d.ts文件&#xff0c;就新建 declare module "*.vue" {import { DefineComponent } from "vue";const component: DefineComponent<{}, {}, any>;export default component; }2&#xff1a;如果有tsconfig.json文…

计算机视觉与深度学习 | 基于MATLAB的图像特征提取与匹配算法总结

基于MATLAB的图像特征提取与匹配算法全面指南 图像特征提取与匹配 基于MATLAB的图像特征提取与匹配算法全面指南一、图像特征提取基础特征类型分类二、点特征提取算法1. Harris角点检测2. SIFT (尺度不变特征变换)3. SURF (加速鲁棒特征)4. FAST角点检测5. ORB (Oriented FAST …

如何通过API接口获取淘宝商品列表?操作详解

一、准备工作 注册开发者账号 访问淘宝开放平台官网/万邦开放平台&#xff0c;完成企业开发者认证&#xff08;个人账号权限受限&#xff09;&#xff0c;使用已有淘宝账号可直接登录。创建应用并填写基本信息&#xff08;如应用名称、类型等&#xff09;&#xff0c;系统生成A…

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…

DataGridView关闭默认第一列及表头居中设置

1、关闭默认第一列 如上图所示&#xff0c;C#和VB.net中的DataGridView控件都是有一个默认的第一列&#xff08;虽然是空白&#xff09;的&#xff0c;如何关闭这个默认列呢&#xff1f; 把“RowHeadersVisible”的值设置成“false”就可以了&#xff1a; 2、表头居中显示 如上…

nodejs express 打包部署

当前文件路径 webpack.config.js const path require(path); module.exports {entry: ./app.js, // Express 入口文件target: node, // 指定 Node.js 环境output: {path: path.resolve(__dirname, dist),filename: bundle.js},mode: production };打包命令 npx webpac…

CentOS 7 修改为静态 IP 地址完整指南

在企业网络环境中,服务器通常需要配置静态 IP 地址以确保网络连接的稳定性和可管理性。以下是使用 NetworkManager 工具在 CentOS 7 系统中将动态 IP 配置修改为静态 IP 的完整指南: 一、检查当前网络配置 查看网络连接状态: 使用 nmcli connection show 命令列出所有网络连…

微信小程序动态组件加载的应用场景与实现方式

动态组件加载的应用场景与实现方式 你提供的代码展示了微信小程序中动态加载组件的方法&#xff0c;但这种方式在实际开发中需要注意使用场景和实现细节。下面我来详细说明如何应用&#xff1a; 应用场景 按需加载组件&#xff1a;在某些条件满足时才加载组件动态配置组件&a…

学习记录: 使用react-router-dom

假设有一个vite创建的react项目,先npm install react-router-dom. 在app中: import { RouterProvider, createBrowserRouter } from "react-router-dom"; import Login from "./comm/Login"; import Home from "./comm/Home"; import TotalMan…

Angular中Webpack与ngx-build-plus 浅学

Webpack 在 Angular 中的概念 Webpack 是一个模块打包工具&#xff0c;用于将多个模块和资源打包成一个或多个文件。在 Angular 项目中&#xff0c;Webpack 负责将 TypeScript、HTML、CSS 等文件打包成浏览器可以理解的 JavaScript 文件。Angular CLI 默认使用 Webpack 进行项目…

java中word快速转pdf

java中word快速转pdf 网上其他方法转pdf要不转的太慢&#xff0c;要不就是损失格式&#xff0c;故而留下此方法留作备用。 文章目录 java中word快速转pdf一、依赖二、依赖包三、代码 一、依赖 <dependency><groupId>com.aspose</groupId><artifactId>…

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…

Unity使用代码分析Roslyn Analyzers

一、创建项目&#xff08;注意这里不要选netstandard2.1会有报错&#xff09; 二、NuGet上安装Microsoft.CodeAnalysis.CSharp 三、实现[Partial]特性标注的类&#xff0c;结构体&#xff0c;record必须要partial关键字修饰 需要继承DiagnosticAnalyzer 注意一定要加特性Diagn…

knife4j:4.3.0 default-flat-param-object: true 没有生效

Get 方式请求 前端接口文档中的键值对方式&#xff08;get&#xff09;发送对象参数&#xff0c;将对象请求参数展开

C++.OpenGL (15/64)Assimp(Open Asset Import Library)

Assimp(Open Asset Import Library) 3D模型加载核心流程 #mermaid-svg-cKmTZDxPpROr7ly1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-cKmTZDxPpROr7ly1 .error-icon{fill:#552222;}#mermaid-svg-cKmTZDxPpROr…