2022年1月3日 星期一

Flutter 應用程式 (Application) 專案範例

Flutter  提供應用程式(Application)專案範例,主要提供下列功能說明:

  1. 如何在 MaterialApp 類別中運用浮動按鍵 (floatingActionButton) 的方法
  2. 如何使用可變狀態物件( StatefulWidget) 類別建立更新介面時可保存動態更新資訊的方法

 1.        建立新的Flutter專案

1-1.        開啟命令介面

 

1-2.        選擇建立應用程式專案類型

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 函式為啟動程式的入口函式。

     若要直接引用存放於此目錄下的檔案的格式如下:

  •   引用同層目錄的檔案:import "檔案名稱";
  •   引用子目錄的檔案: import "子目錄名稱/檔案名稱";
  •   引用上層目錄的檔案: import "../目錄名稱/檔案名稱";

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}

2-3.  test目錄

       主要存放使用Flutter中WidgetTester的測試程序對指定Widget物件進行互動驗證程式,此範例專案提供一個測試範例:

  •     widget_test.dart

   測試自訂MaterialApp在建立時介面是否包含有0的字串和沒有1的字串,若不是則會在執行時產生例外,若是則觸發 add icon 的tap並最後確認其介面是否包含有1的字串和沒有0的字串,若不是則會在執行時產生例外。 

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_application/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}

2-4.  pubspec.yaml檔案

flutter 專案中的檔案配置檔,除了設定基本專案資訊並可設定專案中使用到的相依類別庫或外部資源。

name: flutter_application
description: A new Flutter project.
version: 1.0.0+1

environment:
   sdk: ">=2.15.1 <3.0.0"

dependencies:
flutter:
   sdk: flutter

cupertino_icons: ^1.0.2

dev_dependencies:
flutter_test:
   sdk: flutter

flutter_lints: ^1.0.0

flutter:
     uses-material-design: true

2-5.  .packages檔案

flutter 專案中設定相依類別庫檔案路徑的組態檔,建立專案的預設檔案路徑為 flutter_application: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/
cupertino_icons:file:///D:/flutter_windows_2.8.1-stable/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.4/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_test:file:///D:/flutter_windows_2.8.1-stable/flutter/packages/flutter_test/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_application:lib/

3.  Flutter 預設應用程式專案的基本程式架構

  一個最基本的Material App的應用程式,至少包含一個MaterialApp 與 Scaffload兩個類別;因此在建立Application專案時會自動產生其基本的運用方法,後續可以依照需求針對MaterialApp 及Scaffload兩個類別所提供的參數進行程式外觀及操作介面的調整。

 3-1.  建立 MaterialApp 類別

建立以Material Style為基礎的Widget App 類別並且以 Stateless Widget 類別 Wrap 為不需要可變狀態的物件。

在預設的模式下只有針對MaterialApp 的title 參數設定名稱(此參數只有在Android平台中才有用)及使用ThemeData 結構中primarySwatch欄位來AppBar的預定顏色。

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

 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
     ),
     home: const MyHomePage(title: 'Flutter Demo Home Page'),
   );
 } 
}

3-2.  建立 Scaffold 類別

使用 Scaffold 類別作為初始化MaterialAppClass的相關參數,並且以 StatefulWidget 類別 Wrap 為可變狀態的物件用來保存目前_counter值。

在預設的模式下只有針對Scaffold的appBar 、body 及floating ActionButton 欄位進行簡易的設定。

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
   setState(() {
   	_counter++;
  	});
  }

 @override
 Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
     title: Text(widget.title),
    ),
    body: Center(
    child: Column(
     mainAxisAlignment: MainAxisAlignment.center,
     children: <Widget>[
       const Text(
         'You have pushed the button this many times:',
       ),
       Text(
         '$_counter',
         style: Theme.of(context).textTheme.headline4,
       ),
     ],
    ),
   ),
   floatingActionButton: FloatingActionButton(
    onPressed: _incrementCounter,
    tooltip: 'Increment',
    child: const Icon(Icons.add),
   ),
  );
 }
} 

4.        執行各平台Flutter 偵錯

4-1.        Windows Desktop

2-2.        Chrome Web

2-3.        Linux APP (Ubuntu)

2-4.        Android APP

在執行Android APP時,若無實體裝置需要先開啟Android Studio並使用AVD Manage建立模擬Android裝置

 

執行時選擇所要執行的Android裝置