Flutter 骨架 (Skeleton) 專案範例

閱讀時間約 23 分鐘
  Flutter 提供骨架(Skeleton)專案範例,主要提供下列功能說明:
  1. 專案中新增/設定本地化( Localizations)檔案
  2. 程式中動態切換主題(Theme)的方法
  3. 導航與路由 (Navigate & Routing)的方法

1.  建立新的Flutter專案

  1-1.  開啟命令介面

  1-2.  選擇建立骨架 (Skeleton) 專案類型

  1-3.  輸入專案名稱

2.  Flutter 預設骨架專案的檔案架構

  在選擇建立新的骨架專案後會自動產生相關的檔案及目錄,主要的檔案如下:

  2-1.  build目錄

    儲存各平台建置完成後產生的執行檔案
    (1)  app/outputs/apk -
      選擇建置andoird平台後所產生的apk檔
    (2) windows/runner/ -
      選擇建置 windows平台後所產生的exe及dll檔案。
    (3)  web
      選擇建置web平台後所產生相關的html及js檔案。
    (4)  linux/x64/release/bundle
      選擇建置linux平台後所產生的執行檔及.so檔案。

  2-2.  lib目錄

    主要存放開發程式碼的目錄,main.dart 中的 main 函式為啟動程式的入口函式,而此範例程式使用非同步的方法載入主題(Thmem)的資料,因此在main 函式後加入 async 關鍵字。
若要直接引用存放於此目錄下的檔案的格式如下:
  •   引用同層目錄的檔案:import "檔案名稱";
  •   引用子目錄的檔案: import "子目錄名稱/檔案名稱";
  •   引用上層目錄的檔案: import "../目錄名稱/檔案名稱";
import 'package:flutter/material.dart';
import 'src/app.dart';
import 'src/settings/settings_controller.dart';
import 'src/settings/settings_service.dart';
void main() async {
  final settingsController = SettingsController(SettingsService());
  await settingsController.loadSettings();
  runApp(MyApp(settingsController: settingsController));
}

  2-3.  test目錄

     主要存放使用Flutter中WidgetTester的測試程序對指定Widget物件進行互動驗證程式與 test 測試函數進行自訂函數的驗證而 group 函數為可組合多次連續測試程序,此範例專案提供兩個測試範例:
  1.  unit_test.dart
     測試自訂的1+1是否等於二的函數正確性,若正確則會回傳test函數中定義的字串,若不是則會在執行時產生例外。
import 'package:flutter_test/flutter_test.dart';
void mn() {
  group('Plus Operator', () {
    test('should add two numbers together', () {
      expect(1 + 1, 2);
    });
  });
}    
  2.  widget_test.dart
    測試自訂MaterialApp在建立時是否會包含多於一個Text物件,若正確則會回傳execpt函數中定義的字串,若不是則會在執行時產生例外。
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
  group('MyWidget', (){
    testWidgets('should display a string of text', (WidgetTester tester) async {  
    // Define a Widget
    const myWidget = MaterialApp(
      home: Scaffold(
        body: Text('Hello'),
      ),
    );
    // Build myWidget and trigger a frame.
    await tester.pumpWidget(myWidget);
    // Verify myWidget shows some text
    expect(find.byType(Text), findsOneWidget);
   });
 });
}

  2-4.  pubspec.yaml檔案

    flutter 專案中的檔案配置檔,除了設定基本專案資訊並可設定專案中使用到的相依類別庫或外部資源。
name: flutter_skeleton
description: A new Flutter project.
# Prevent accidental publishing to pub.dev.
publish_to: 'none'
version: 1.0.0+1
environment:
  sdk: ">=2.15.1 <3.0.0"
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations: 
    sdk: flutter
    version: ^0.0.0
dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^1.0.0
flutter:
  uses-material-design: true
  # Enable generation of localized Strings from arb files.
  generate: true
  assets:
  # Add assets from the images directory to the application.
  - assets/images/

  2-5.  .packages檔案

    flutter 專案中設定相依類別庫檔案路徑的組態檔,建立專案的預設檔案路徑為 flutter_skeleton:lib/ 而此檔案是在執行"flutter pub get"指令後根據 pubspec.yaml中的內容產生出來,設定引用類別庫格式為【路徑別名:實際路徑】。
async:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.8.2/lib/
boolean_selector:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/
characters:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/
charcode:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib/
clock:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib/
collection:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib/
fake_async:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib/
flutter:file:///D:/flutter_windows_2.8.1-stable/flutter/packages/flutter/lib/
flutter_lints:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-1.0.4/lib/
flutter_localizations:file:///D:/flutter_windows_2.8.1-stable/flutter/packages/flutter_localizations/lib/
flutter_test:file:///D:/flutter_windows_2.8.1-stable/flutter/packages/flutter_test/lib/
intl:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib/
lints:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/lints-1.0.1/lib/
matcher:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.11/lib/
meta:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/
path:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib/
sky_engine:file:///D:/flutter_windows_2.8.1-stable/flutter/bin/cache/pkg/sky_engine/lib/
source_span:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib/
stack_trace:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/
stream_channel:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/
string_scanner:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib/
term_glyph:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib/
test_api:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.3/lib/
typed_data:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib/
vector_math:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.1/lib/
flutter_skeleton:lib/

  2-.6.  I10n.yaml

    flutter 專案中的本地化(localization)配置檔,主要用來設定放置不同本地化(Localization)檔案路徑、預設本地化檔案及產生出載入本地化檔案的程式檔名稱。
arb-dir: lib/src/localization
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
    此範例專案只有建立基本的本地化(localication) arb 檔案
{
  "appTitle": "flutter_skeleton",
  "@appTitle": {
    "description": "The title of the application"
  }
}
    若專案中有出現無法載入本地化(localization)檔案,則可在Terminal 視窗中執行 「flutter pub add "gen_l10n/app_localizations.dart"」於.dart_tool目錄下產生相應的目錄及檔案。

3.  Flutter 預設骨架專案的基本架構

  一個最基本的 MaterialApp 的骨架 (Skeleton) 程式,至個 MaterialApp 與 AnimatedBuilder 兩個類別並搭配以混入 (mixins) ChangeNotifier 類別的方式自訂 SettingsController 類別作為主題 (Theme) 切換時產生通知事件的參數。
  因此在建立 Skeleton 專案時會自動產生其基本的運用方法,後續可以依照需求針對 AnimatedBuilder 及 MaterialApp 兩個類別所提供的參數進行程式外觀及操作介面的調整。
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'sample_feature/sample_item_details_view.dart';
import 'sample_feature/sample_item_list_view.dart';
import 'settings/settings_controller.dart';
import 'settings/settings_view.dart';
/// The Widget that configures your application.
class MyApp extends StatelessWidget {
  const MyApp({ Key? key, required this.settingsController,})
               : super(key: key);
  final SettingsController settingsController;
  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: settingsController,
      builder: (BuildContext context, Widget? child) {
        return MaterialApp(
         restorationScopeId: 'app',
         localizationsDelegates: const [
           AppLocalizations.delegate,
           GlobalMaterialLocalizations.delegate,
           GlobalWidgetsLocalizations.delegate,
           GlobalCupertinoLocalizations.delegate,
         ],
         supportedLocales: const [
           Locale('en', ''), // English, no country code
         ],          
         onGenerateTitle: (BuildContext context) => 
                  AppLocalizations.of(context)!.appTitle,
         
         theme: ThemeData(),
         darkTheme: ThemeData.dark(),
         themeMode: settingsController.themeMode,
 
         onGenerateRoute: (RouteSettings routeSettings) {
           return MaterialPageRoute<void>(
             settings: routeSettings,
             builder: (BuildContext context) {
               switch (routeSettings.name) {
                 case SettingsView.routeName:
                   return SettingsView(controller: settingsController);
                 case SampleItemDetailsView.routeName:
                   return const SampleItemDetailsView();
                 case SampleItemListView.routeName:
                 default:
                   return const SampleItemListView();
             }},
         );}
      );},
   );}
}

4.  執行各平台Flutter 偵錯

  點選右下角No Devices項目後切換至要執行偵錯的平台並執行 Run -> Start Debugging (F5) 進行偵錯

  4-1.  Windows Desktop

  4-2.  Chrome Web

  4-3.  Linux APP (Ubuntu)

  4-4.  Android APP

    在執行Android APP時,若無實體裝置需要先開啟Android Studio並使用AVD Manager建立模擬Android裝置
  執行時選擇所要執行的Android裝置
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
說明Flutter 應用軟體(Application)專案範例的架構與在各平台執行的顯示畫面
說明如何在Windows系統中安裝 Flutter 與 Visual Studio Code 的開發環境
說明如何在Linux系統中安裝 Flutter 與 Visual Studio Code 開發環境
說明Flutter 應用軟體(Application)專案範例的架構與在各平台執行的顯示畫面
說明如何在Windows系統中安裝 Flutter 與 Visual Studio Code 的開發環境
說明如何在Linux系統中安裝 Flutter 與 Visual Studio Code 開發環境
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
Flutter is a powerful, open-source UI software development kit created by Google.
Thumbnail
解析成List List items=json.decode(jsonStr); print(items[0]["your_key"]); 解析成Map Map<String, dynamic> user = json.decode(json); print('${user['your_k
Thumbnail
這邊會使用WebSocketChannel去與http://www.websocket.org做連線。 連線 final channel = IOWebSocketChannel.connect('wss://echo.websocket.events'); 接收 StreamBui
Thumbnail
Dio是一個Dart Http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載、逾時等。 加入 dependencies: dio: ^x.x.x #请使用pub上的最新版本 使用 GET Response response;
Thumbnail
配置 idleTimeout:在httpClient請求結束後,會繼續保持連線,直到超過idleTimeout值才會關閉連接。 connectionTimeout:和伺服器建立連線逾時,如果超過connectionTimeout值則會拋出SocketException異常。 maxConnec
Thumbnail
「我不覺得我自己有什麼文學的聲量,我一直以來都不是很care這些東西。我做個比喻好了:百年老店到了分家的時候,你總是知道,最得你意的是哪一間嘛。」
Thumbnail
五月初我搭高鐵南下,陪媽咪骨科回診。主要是因爲她的腳先前有跌倒過,後來導致膝蓋受傷,也沒有特別理會它,等到覺得每晚膝蓋痛到睡不著,才發現事態嚴重了。後來,她有去醫院做過膝關節微創手術,打過玻尿酸都尚未有所改善。
Thumbnail
上架強調順手與否,一個平凡的五層架,,這些東西該如何配置呢? 頂樓:體積大而輕 例如:空紙箱、空收納盒、小毯子、枕頭 四樓:輕巧常使用 例如:帽子、包包、或其他出門隨手就要拿的到的物品 三樓:常用,要拿很順手 例如:零食、保養品、不同用途的電線、保健食品等 二樓:易碎物品,彎腰沒關西 例如:玻璃瓶、
突破框架 框架是需要突破的,這個社會上存在著很多不必要的框架,舉個例子:「性別」。這個例子在最近幾年特別被大眾關注。社會性別可以是指區分男性與女性的氣質,也可能是指生物上的男性、女性。在以前,都會使用二分法或是說性別二元論,你是男生或是女生,不是男的就是女......
Thumbnail
首先是本次重頭戲【#零瑕肌密微光粉底液】 這款粉底的質地是偏霧帶有一咪咪光澤,所以不會死霧到很像假面,遮瑕度我覺得是有的喔,基本上我明顯的大瑕疵都有很好的遮住 如果真的很深的痘印,會建議你底妝前遮瑕,但個人覺得這罐的遮瑕度日常很夠用了
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
Flutter is a powerful, open-source UI software development kit created by Google.
Thumbnail
解析成List List items=json.decode(jsonStr); print(items[0]["your_key"]); 解析成Map Map<String, dynamic> user = json.decode(json); print('${user['your_k
Thumbnail
這邊會使用WebSocketChannel去與http://www.websocket.org做連線。 連線 final channel = IOWebSocketChannel.connect('wss://echo.websocket.events'); 接收 StreamBui
Thumbnail
Dio是一個Dart Http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載、逾時等。 加入 dependencies: dio: ^x.x.x #请使用pub上的最新版本 使用 GET Response response;
Thumbnail
配置 idleTimeout:在httpClient請求結束後,會繼續保持連線,直到超過idleTimeout值才會關閉連接。 connectionTimeout:和伺服器建立連線逾時,如果超過connectionTimeout值則會拋出SocketException異常。 maxConnec
Thumbnail
「我不覺得我自己有什麼文學的聲量,我一直以來都不是很care這些東西。我做個比喻好了:百年老店到了分家的時候,你總是知道,最得你意的是哪一間嘛。」
Thumbnail
五月初我搭高鐵南下,陪媽咪骨科回診。主要是因爲她的腳先前有跌倒過,後來導致膝蓋受傷,也沒有特別理會它,等到覺得每晚膝蓋痛到睡不著,才發現事態嚴重了。後來,她有去醫院做過膝關節微創手術,打過玻尿酸都尚未有所改善。
Thumbnail
上架強調順手與否,一個平凡的五層架,,這些東西該如何配置呢? 頂樓:體積大而輕 例如:空紙箱、空收納盒、小毯子、枕頭 四樓:輕巧常使用 例如:帽子、包包、或其他出門隨手就要拿的到的物品 三樓:常用,要拿很順手 例如:零食、保養品、不同用途的電線、保健食品等 二樓:易碎物品,彎腰沒關西 例如:玻璃瓶、
突破框架 框架是需要突破的,這個社會上存在著很多不必要的框架,舉個例子:「性別」。這個例子在最近幾年特別被大眾關注。社會性別可以是指區分男性與女性的氣質,也可能是指生物上的男性、女性。在以前,都會使用二分法或是說性別二元論,你是男生或是女生,不是男的就是女......
Thumbnail
首先是本次重頭戲【#零瑕肌密微光粉底液】 這款粉底的質地是偏霧帶有一咪咪光澤,所以不會死霧到很像假面,遮瑕度我覺得是有的喔,基本上我明顯的大瑕疵都有很好的遮住 如果真的很深的痘印,會建議你底妝前遮瑕,但個人覺得這罐的遮瑕度日常很夠用了