iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Mobile Development

Flutter基礎入門系列 第 4

【Day 04】製作第一個app

  • 分享至 

  • xImage
  •  

今天,筆者將跟著google所製作的教學一起學習製作人生中第一個App:一個簡單,隨機選擇兩個英文文字並將他們合併,且使用者可以儲存喜歡的生成詞語。當然,因為是使用Flutter製作的,所以能夠在Android, Web, Linux等平台上運作。
本篇裡,筆者將使用NeoVim實做,並會記下自己的過程,供大家參考。
Codelab教學連結


前製準備

  1. 選擇編輯器
    常見的幾個選項:VS Code, Android Studio, IntelliJ IDE都適合用於編輯,筆者出於自身習慣,選擇使用Neovim,並用了nvim-flutter/flutter-tools.nvim這個plugin。
  2. 選擇應用程式主要使用平台
    官方建議可以先選好主要使用者在的平台,像是Android等,而這可以由將裝置與電腦連線(由usb線等方式),並於開發時的flutter device設定目標平台。
    使用Web作為目標平台在開發時固然方便,但Web不支援即時更新我們在程式碼中做的變動,這點須注意。
  3. 下載安裝Flutter SDK
    可以參考筆者的前一篇文官方說明文件

建立新專案

首先,在Terminal中輸入以下程式碼,以建立一個全新的專案。專案名字可以自行依心情設定。

flutter create first_app

如同上次我們建立測試執行檔test_drive,此時它也幫我們建立好一個名為first_app的資料夾。資料夾的結構如下:
https://ithelp.ithome.com.tw/upload/images/20240918/20169446wxwUt90384.png
圖片中所開啟的檔案lib/main.dart便是我們專案主要編輯的檔案。

專案基本資訊:pubspec.yaml

pubspec.yaml存有著我們所編輯中專案的一些基本資訊,如名稱、版本、所需資料庫等等的內容。
為了增加我們應用程式中所有的英文單字,我們需要到此檔案中更改一些設定。
到檔案中dependencies(第30行)項增加英文單字的packages:

dependencies:
  flutter:
    sdk: flutter

  english_words: ^4.0.0
  provider: ^6.0.0

分析器設定:analysis_options.yaml

此檔案適用於設定Flutter在分析我們的檔案時所需要的一些規則,現在所條的設定十分寬鬆,考量到這是我們的第一次實做,之後隨時都可以更改這裡的設定,將它變得更嚴謹。
我們開啟analysis_options.yaml,增加一些linter rules:

include: package:flutter_lints/flutter.yaml

linter:
  rules:
    avoid_print: false
    prefer_const_constructors_in_immutables: false
    prefer_const_constructors: false
    prefer_const_literals_to_create_immutables: false
    prefer_final_fields: false
    unnecessary_breaks: true
    use_key_in_widget_constructors: false

設定main.dart

在開始編輯main.dart之前,可以先跑一次flutter test,這會測試我們更改yaml檔後程式是否可以正確執行,並下載剛剛於pubspec.yaml檔增加的packages,方便我們編輯時的autocompletion運作。

應用程式基底

開啟我們的lib/main.dart,並將檔案中的程式碼由以下內容取代:

import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyAppState(),
      child: MaterialApp(  //sets the theme/look of the app
        title: 'Namer App',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random idea:'),
          Text(appState.current.asLowerCase),
        ],
      ),
    );
  }
}

p.s. 此時如果我們去執行flutter test做測試,會顯示出:Conter increments smoke test Test faild.,但使用flutter run卻能夠正常執行,可以想想看是為什麼呢~

建立按鈕

我們來建立一個用於生成下一組隨機詞組的按鈕:Next
在main.dart檔案最下方class MyHomePage的Scaffold中增加ElevatedButton,如下方所示:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random idea:'),
          Text(appState.current.asLowerCase),

          ElevatedButton(onPressed: () {
              print('button pressed!');
            },
            child: Text('Next'),
          )
        ],
      ),
    );
  }
}

我們此時執行flutter run時,便能看到我們的小程式有了個按鈕,每次按了按鈕,雖然在應用程式的界面上看不到什麼改變,但在__FLUTTER_DEV_LOG__中都會印出'button pressed!'的字樣。
https://ithelp.ithome.com.tw/upload/images/20240918/20169446iBbY5t3pR2.png

增加按鈕功能

想給我們的按鈕增加功能,我們要在class MyAppState extends ChangeNotifier中增加一個函式:getNext(),顧名思義,就是獲得下一個詞組。

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();

  void getNext() {
    current = WordPair.random();
    notifyListeners();
  }
}

我們還需要讓按鈕被按下時呼叫函式。記得我們在前面建立按鈕時讓它被按下時印出'button pressed!'嗎?此時,我們只需要在那行之上呼叫appState.getNext(),便能夠顯示下一個隨機詞組。

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random idea:'),
          Text(appState.current.asLowerCase),

          ElevatedButton(onPressed: () {
              appState.getNext();
              print('button pressed!');
            },
            child: Text('Next'),
          )
        ],
      ),
    );
  }
}

hot reload即時更新

在執行`flutter run時,筆者稍稍更改了按鈕上的文字,而不須重開應用程式,我們的app立刻就顯示出剛剛所作的更新內容,是不是很方便,能即時看到改變!這也是Flutter在開發時我們可以使用的一大優勢之一。
https://ithelp.ithome.com.tw/upload/images/20240918/201694468026rcoYqW.png


因為顯示問題,在markdown程式碼區塊無法顯示dart的程式碼,因此部份區塊未設定程式碼語言,若閱讀造成不便,敬請見諒m(__)m

今天分享的內容就到這裡啦,明天我們將會在這個應用程式中做出更多的延伸,增加可儲存喜歡的詞組這個功能,以及美化應用程式。若有任何想法,都歡迎留言或email,謝謝今天讀到這裡的讀者,我們明天見!


上一篇
【Day 03】下載與測試
下一篇
【Day 05】製作一個app - 排版設計
系列文
Flutter基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
arguskao
iT邦新手 3 級 ‧ 2024-09-28 13:01:06

此時如果我們去執行flutter test做測試,會顯示出:Conter increments smoke test Test faild.,但使用flutter run卻能夠正常執行,可以想想看是為什麼呢~

答案是什麼呢?

nny02426 iT邦新手 5 級 ‧ 2024-09-29 20:16:58 檢舉

test是用於測試在執行時有沒有可能會產生讓程式crash的錯誤,並不代表無法程式跑不動。

Smoke Test這個詞的來源有個說法是從硬體而來:「如果裝置被啟動了,會不會冒煙出問題?」並在冒煙時就先解決問題避免產生更大的損失(裝置燒起來)。但裝置冒煙時還是可以運作的,只是它之後可能就會壞掉。

關於smoke test是參考以下文章內容:

0
arguskao
iT邦新手 3 級 ‧ 2024-09-29 09:16:00

做到這一步,按Next,上面的英文會改變嗎?

nny02426 iT邦新手 5 級 ‧ 2024-09-29 20:24:08 檢舉

會哦!在這程式中生成的英文詞組是存在appStatecurrent中,而使用appState.getNext()便會更改current所存的內容。

我要留言

立即登入留言