chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Flutter如何將代碼顯示到界面上呢?

OSC開源社區(qū) ? 來源:OSCHINA 社區(qū) ? 2023-05-10 10:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

如何優(yōu)雅的將項目中的代碼,亦或是你的 demo 代碼展示到界面上?本文對使用簡單、便于維護且通用的解決方案,進行相關(guān)的對比和探究

為了節(jié)省大家的時間,把最終解決方案的相關(guān)接入和用法寫在前面

預覽代碼

快速開始

接入:pub,github

dependencies:
  code_preview: ^0.1.5

用法:CodePreview,提供需要預覽的 className,可自動匹配該類對應(yīng)的代碼文件

本來想把寫法簡化成傳入對象,但是因為一些原因無奈放棄,改成了className

具體可以參考下面Flutter Web中的問題模塊的說明

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

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(className: 'Test');
  }
}

使用效果:flutter_smart_dialog

06191504-ee71-11ed-90ce-dac502259ad0.png

配置代碼文件

因為原理是遍歷資源文件,所以必須將需要展示的代碼文件或者其文件夾路徑,定義在 assets 下,這步操作,為大家提供了一個自動化的插件解決

強烈建議需要展示到界面的代碼,都放在統(tǒng)一的文件夾里管理

展示界面的代碼需要在 pugspec.yaml 中的 assets 定義

063e2df8-ee71-11ed-90ce-dac502259ad0.png

如果代碼預覽的文件夾,分級復雜,每次都需要定義路徑實在麻煩

提供一個插件:Flutter Code Helper

安裝:Plugins 中搜索Flutter Code Helper

066af856-ee71-11ed-90ce-dac502259ad0.png

pugspec.yaml 中定義下需要自動生成文件夾的路徑,文件夾隨便套娃,會自動幫你遞歸在 assets 下生成

不需要自動生成,可:不寫該配置,或者配置空數(shù)組(auto_folder: [])

code_helper:
  auto_folder: [ "assets/", "lib/widgets/" ]

說明下:上面的插件是基于 RayC 的 FlutterAssetsGenerator 插件項目改的

看了下 RayC 的插件代碼和相關(guān)功能,和我預想的上面功能實現(xiàn)有一定出入,改動起來變動較大

想試下插件項目的各種新配置,直接拉到最新

后期如果想到需要什么功能,方便隨時添加

所以沒向其插件里面提 pr,就單獨新開了個插件項目

高級使用

主題

提供倆種代碼樣式主題

日間模式

CodePreview.config = CodePreviewConfig(codeTheme: CodeTheme.light);

06816ae6-ee71-11ed-90ce-dac502259ad0.png

夜間模式

CodePreview.config = CodePreviewConfig(codeTheme: CodeTheme.dark);

06a70c42-ee71-11ed-90ce-dac502259ad0.png

注釋解析

你可以使用如下的格式,在類上添加注釋

key 的前面必須加@,舉例(@title,@xxx)

key 與 value 的之間,必須使用分號分割,舉例(@xxx: xxx)

value 如果需要換行,換行的文案前必須加中劃線

/// @title:
///  - test title one
///  - test title two
/// @content: test content
/// @description: test description
class OneWidget extends StatelessWidget {
  const OneWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

然后可以從customBuilder的回調(diào)獲取 param 參數(shù),param 中擁有 parseParam 參數(shù)

獲取取得上面注釋的數(shù)據(jù):param.parseParam ['title'] 或者 param.parseParam ['***']

獲取的 value 的類型是 List,可兼容多行 value 的類型

customBuilder的用法

codeWidget內(nèi)置的代碼預覽布局,如果你想定義自己預覽代碼的布局,那就可以不使用codeWidget

一般來說,可以根據(jù)注釋獲取的數(shù)據(jù),結(jié)合codeWidget嵌套來自定義符合要求的布局

param中含有多個有用內(nèi)容,可自行查看

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

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CodePreview(
      className: 'OneWidget',
      customBuilder: (Widget codeWidget, CustomParam? param) {
        debugPrint(param?.parseParam['title'].toString());
        debugPrint(param?.parseParam['content'].toString());
        debugPrint(param?.parseParam['description'].toString());
        return codeWidget;
      },
    );
  }
}

目前內(nèi)部預覽的布局,會自動去掉類上的注釋,如果想保留注釋,可自行匹配下

 CodePreview.config = CodePreviewConfig(removeParseComment: false);

幾種代碼預覽方案

FlutterUnit 方案

FlutterUnit 項目也是自帶代碼預覽方案,這套方案是比較特殊方案

大概看了下,整個 FlutterUnit 的數(shù)據(jù)都是基于flutter.db,該文件里面就有相關(guān) demo 的文本信息

所有的 demo 也是單獨存在一個叫widgets的項目中

所以大概可以猜測出

應(yīng)該會有個 db 的輔助工具,會去掃描widgets的項目中的 demo 代碼

將他們的文本信息都掃描出來,然后解析上面的注釋等相關(guān)信息,分類存儲到數(shù)據(jù)庫中,最后生成 db 文件

06bf34fc-ee71-11ed-90ce-dac502259ad0.png

映射表,宿主可以通過 db 中的組件類名,從這里拿到 demo 效果實例

0700048c-ee71-11ed-90ce-dac502259ad0.png

總結(jié)

整套流程看下來,實現(xiàn)起來的工作量還是有點大的

db 輔助工具的編寫

文本注釋相關(guān)解析規(guī)則

如何便捷的維護 db 文件(輔助工具是否支持,生成后自動覆蓋宿主 db 文件)

不同平臺 db 文件的讀取和相關(guān)適配

優(yōu)點

因為掃描工具不依賴 Flutter 相關(guān)庫,預覽方案可以快速的移植到其它編程語言(compose,SwiftUI 等)

具備高度自定義,因為是完全獨立的第三方掃描工具,可以隨性所欲的定制化

缺點

最明顯的缺點,應(yīng)該就是稍微改下 demo 代碼,就需要三方工具重新生成 db 文件(如果三方工具實現(xiàn)的是 cli 工具,可以將掃描生成命令和 push 等命令集成一起,應(yīng)該可以比較好的避免該問題)

build_runner 方案

build_runner 是個強大代碼自動生成工具,根據(jù) ast 語法樹 + 自定義注解信息,可以生成很多強大的附屬代碼信息,例如json_serializable等庫

所以,也能利用這點自定義類注解,獲取到對應(yīng)的整個類的代碼信息,在對應(yīng)附屬的xx.g.dart文件中,將獲取的代碼內(nèi)容轉(zhuǎn)換成字符串,然后直接將xx.g.dart文件的代碼字符串信息,展示到界面就行了

優(yōu)點

可以通過生成命令,全自動的生成代碼,甚至將整個預覽 demo 的映射表都可以自動配置完成

可以規(guī)范的通過注解配置多個參數(shù)

缺點

因為build_runner需要解析整個 ast 語法樹,一旦項目很大之后,解析生成的時間會非常非常的長!

因為現(xiàn)在很多的這類庫都是依賴build_runner,所以跑自動生成命令,會導致巨多xx.g.dart文件被改動,極大的增加 cr 工作量

資源文件方案

這應(yīng)該最常用的一種方案

在pubspec.yaml中的assets中定義下我們代碼文件路徑

flutter:
  assets:
    - lib/widgets/show/

然后用 loadString 獲取文件內(nèi)容

final code = await rootBundle.loadString('lib/widgets/show/custome_dialog_animation.dart');

072a8b8a-ee71-11ed-90ce-dac502259ad0.png

優(yōu)點

侵入性非常低,不會像build_runnner方案那樣影響到其它模塊

便于維護,如果 demo 預覽代碼被改變了,打包的時候,資源文件也會生成對應(yīng)改變后的代碼文件

缺點

使用麻煩,使用的時候需要傳入具體的文件路徑,才能找到想要的代碼資源文件

需要反復的在pubspec.yaml中的assets里面定義文件路徑

資源文件方案優(yōu)化

上面的三種方案各有優(yōu)缺點,明確當前的訴求

目前是想寫個簡單的,通用的,僅在 Flutter 中實現(xiàn)代碼預覽方案

要求使用簡單,高效

維護簡單,多人開發(fā)的時候不會有很大成本

FlutterUnit 方案:實現(xiàn)起來成本較大,且多人開發(fā)對單個 db 文件的維護很可能會有點問題,例如:更新代碼的時候,db 文件忘記更新

build_runner 方案:生成時間是個問題,還有很對其他類型xx.g.dart文件產(chǎn)生影響也比較麻煩

資源文件方案:整體是符合預期的,但是使用時候,需要傳入路徑和pubspec.yaml中反復定義文件路徑,這是倆個很大痛點

結(jié)合實現(xiàn)成本和訴求,選擇資源文件方案,下面對其痛點進行優(yōu)化

使用優(yōu)化

Flutter 的編譯產(chǎn)物中,有個相當有用的文件:AssetManifest.json

AssetManifest.json 文件里面,有所有的資源文件的路徑,然后就簡單了,我們只需要讀取該文件內(nèi)容

final manifestContent = await rootBundle.loadString('AssetManifest.json');

獲取到所有的路徑之后,再結(jié)合傳入的類名,讀取所有路徑的文件內(nèi)容,然后和傳入的類名做正則匹配就行了

稍微優(yōu)化

將傳入的類名,轉(zhuǎn)換為下劃線名稱和所有路徑名稱做匹配,如果能匹配上,再進行內(nèi)容匹配,匹配成功后就返回該文件的代碼內(nèi)容

如果上述匹配失敗,就進行兜底的全量匹配

優(yōu)化前

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

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(path: 'lib/widgets/show/custome_dialog_animation.dart');
  }
}

優(yōu)化后

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

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(className: 'CustomDialogAnimation');
  }
}

一般來說,我是統(tǒng)一配置預覽 demo 和 className,這樣比較好對照

07509834-ee71-11ed-90ce-dac502259ad0.png

路徑定義優(yōu)化

本來是想在pubspec.yaml的assets里面直接寫通配符定義全路徑,然后悲劇了,它不支持這種寫法

flutter:
  assets:
    - lib/widgets/**/*.dart

GG,只能想其他辦法了,想了很多方法都不行,只能從外部入手,用 idea 插件的形式,實現(xiàn)自動化掃描生成路徑

安裝:Plugins 中搜索Flutter Code Helper

066af856-ee71-11ed-90ce-dac502259ad0.png

pugspec.yaml 中定義下需要自動生成文件夾的目錄,文件夾隨便套娃,會自動幫你遞歸在 assets 下生成

不需要自動生成,可:不寫該配置,或者配置空數(shù)組(auto_folder: [])

code_helper:
  auto_folder: [ "assets/", "lib/widgets/" ]

Flutter Web 中的問題

魔幻的 runtimeType

flutter web 的 release 模式中

dart2js 會壓縮 JS,這樣會使得類型名被改變

例如:dart 中的TestWidgetFunction類的 runtimeType,可能會變成minified:Ah,而不是TestWidgetFunction!

為啥需要壓縮呢?壓縮名稱可以使得編譯器將 JavaScript 體積縮小 3 倍 +;精確等效語義和性能 / 代碼大小之間的權(quán)衡,Dart 明顯是選擇了后者

這種情況只會在 Flutter Web 的 release 模式下發(fā)生,其他平臺和 Flutter web 的 Debug | Profile 模式都不會有這種問題;所以說Xxx.runtimeType.toString,并不一定會得到預期內(nèi)的數(shù)據(jù)。。。

解決思路

將壓縮類型minified:Ah恢復成Test

將獲取的Test字符串使用相同算法壓縮成minified:Ah

如有知道如何實現(xiàn)的,務(wù)必告訴鄙人

下面從壓縮級別調(diào)整的角度,探究是否可解決該問題

dart2js 壓縮說明

注:flutter build web 默認的是 O4 優(yōu)化級別

O0: 禁用許多優(yōu)化。

O1: 啟用默認優(yōu)化 (僅是 dart2js 該命令的默認級別)

O2: 在 O1 優(yōu)化基礎(chǔ)上,尊重語言語義且對所有程序安全的其他優(yōu)化(例如縮?。?/p>

備注:使用 - O2, 使用開發(fā) JavaScript 編譯器編譯時,類型的字符串表示不再與 Dart VM 中的字符串表示相同

O3: 在 O2 優(yōu)化基礎(chǔ)上,并省略隱式類型檢查。

注意:省略類型檢查可能會導致應(yīng)用程序因類型錯誤而崩潰

O4: 在 O3 優(yōu)化基礎(chǔ)上,啟用更積極的優(yōu)化

注意:O4 優(yōu)化容易受到輸入數(shù)據(jù)變化的影響,在依賴 O4 之前,需測試用戶輸入中的邊緣情況

下面是 flutter 新建項目,未做任何改動,不同壓縮級別的 js 產(chǎn)物體積

# main.dart.js: 7.379MB
flutter build web --dart2js-optimization O0 
# main.dart.js: 5.073MB
flutter build web --dart2js-optimization O1
# main.dart.js: 1.776MB
flutter build web --dart2js-optimization O2
# main.dart.js: 1.716MB
flutter build web --dart2js-optimization O3
# main.dart.js: 1.687MB
flutter build web --dart2js-optimization O4

總結(jié)

預期用法

為什么想使用對象?因為當對象名稱改變時,對應(yīng)使用的地方,可以便捷觀察到需要改變

可以使用傳入的對象實例,在內(nèi)部使用 runtimeType 獲取類型名,再進行相關(guān)匹配

CodePreview(code: Test());

但是

綜上可知,使用flutter build web --dart2js-optimization O1編譯的 flutter web release 產(chǎn)物,能夠使得 runtimeType 的語義和 Dart VM 中字符串保持一致

但是該壓縮級別下的,js 體積過于夸張,務(wù)必會對加載速度產(chǎn)生極大影響,可想而知,在復雜項目中的體積增漲肯定更加離譜

對于想要用法更加簡單,使用低級別壓縮命令打包的想法需要舍棄

用法不得已做妥協(xié)

CodePreview(className: "Test");

這是個讓我非常糾結(jié)的思路歷程

最后

到這里也結(jié)束了,自我感覺,對大家應(yīng)該能有一些幫助

一般來說,大部分團隊,都會有個自己的內(nèi)部組件庫,因為 Flutter 強大的跨平臺特性,所以就能很輕松的發(fā)布到 web 平臺,可以方便的體驗各種組件的效果,結(jié)合文章中的代碼預覽方案,就可以更加快速的上手各種組件用法了~





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Rayc
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    6109
  • flutter
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    576

原文標題:Flutter如何將代碼顯示到界面上

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    如何將RT-Thread移植NXP MCUXPressoIDE上

    RT-Thread默認支持的IDE只有IAR 和 Keil, 那如何將RT-Thread移植NXP MCUXPressoIDE上?本文內(nèi)容比較簡單但稍有瑣碎,希望對有需要的小伙伴有所幫助。
    的頭像 發(fā)表于 02-13 10:37 ?1898次閱讀
    <b class='flag-5'>如何將</b>RT-Thread移植<b class='flag-5'>到</b>NXP MCUXPressoIDE上

    鴻蒙Flutter實戰(zhàn):07混合開發(fā)

    # 鴻蒙Flutter實戰(zhàn):混合開發(fā) 鴻蒙Flutter混合開發(fā)主要有兩種形式。 ## 1.基于har flutter module打包成har包,在原生鴻蒙項目中,以har包
    發(fā)表于 10-23 16:00

    鴻蒙Flutter實戰(zhàn):08-如何調(diào)試代碼

    ,找到 Flutter Attach , Flutter 調(diào)試器連接至宿主機 然后就是增加斷點,使用hot reload 重新加載 Flutter,調(diào)試項目
    發(fā)表于 10-23 16:29

    鴻蒙Flutter實戰(zhàn):11-使用 Flutter SDK 3.22.0

    # 使用 Flutter SDK 3.22.0 ## SDK 安裝 參考[鴻蒙Flutter實戰(zhàn):01-搭建開發(fā)環(huán)境]文章的說明,首先安裝 Flutter SDK 3.22.0。 目前鴻蒙化
    發(fā)表于 11-01 15:03

    鴻蒙Flutter實戰(zhàn):14-現(xiàn)有Flutter 項目支持鴻蒙 II

    ).jpeg 總結(jié) 通過 FVM 管理多個 Flutter SDK 版本,僅在鴻蒙調(diào)測打包時,切換到 ohos-flutter SDK 通過 apps 殼工程,鴻蒙化適配的代碼,盡量
    發(fā)表于 12-26 14:59

    深入理解flutter的編譯原理與優(yōu)化

    摘要: 閑魚技術(shù)-正物 問題背景 對于開發(fā)者而言,什么是Flutter?它是用什么語言編寫的,包含哪幾部分,是如何被編譯,運行設(shè)備上的?Flutter如何做到Debug模式Hot
    發(fā)表于 07-02 17:47

    如何將代碼集成Multi IDE Project?

    我想知道是否可以使用PinMap向?qū)蒀代碼以與Multi IDE Green Hill編譯器一起使用,如果可以的話,如何將代碼集成Multi IDE Project? 提前致
    發(fā)表于 06-21 10:05

    界面上顯示和輸入控件特別多時如何管理

    如果在一個界面上有幾十個控件(顯示和輸入都有),類型還不一樣,請問如何管理這些控件,現(xiàn)在我都是用很多事件結(jié)構(gòu)來做的,請問大家有什么好的方法?特別是在ActorFramework框架中。
    發(fā)表于 09-09 19:32

    如何將現(xiàn)有代碼一點點移植HC32F460上

    如何將現(xiàn)有代碼一點點移植HC32F460上?其移植過程是怎樣的?
    發(fā)表于 11-25 06:27

    如何將示例flutter應(yīng)用程序安裝到STM32MP157F-DK2?

    /environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabiexport CC=${CLANGCC}export CXX=${CLANGCXX}我的問題是如何將一個簡單的 flutter 應(yīng)用程序安裝到我的發(fā)現(xiàn)
    發(fā)表于 12-06 07:14

    如何將ST25dv sdk移植Flutter?

    我想開發(fā)一個簡單的應(yīng)用程序來讀/寫 ST25DV 設(shè)備的內(nèi)部 EEPROM。是否有 ST25dv sdk Flutter 的移植?
    發(fā)表于 01-03 09:01

    如何將BLDC進電機控制算法移植STM微控制器上?

    為 STSPIN 提供的 6 步算法。我們應(yīng)該將該代碼移植到任何其他 ST 控制器嗎?如何將BLDC進電機控制算法移植STM微控制器上?
    發(fā)表于 01-17 08:54

    如何將JavaScript代碼嵌入HTML頁面

    本教程向您展示如何將JavaScript代碼嵌入HTML頁面,來幫助您開始學習 JavaScript。
    的頭像 發(fā)表于 12-14 17:46 ?1438次閱讀

    Flutter 共創(chuàng)未來 | Flutter Forward 活動精彩回顧

    。 Flutter Forward 活動 https://flutter.dev/events/flutter-forward Flutter 是一個
    的頭像 發(fā)表于 02-22 23:20 ?852次閱讀

    使用 Flutter SDK 3.27.4構(gòu)建HarmonyOS應(yīng)用

    /flutter_flutter 通過代碼工具下載倉庫代碼并指定h-3.27.4-dev分支。 ? git clone https://gitcode.com/openharmony-sig
    的頭像 發(fā)表于 06-11 09:15 ?314次閱讀