Tag: flutter

  • Flutter 的 ListView 要如何做為 Column 中的項目

    Flutter 的 ListView 要如何做為 Column 中的項目

    有時候為了排版,會需要將 ListView 放到 Column 中,但直接放的話雖然程式碼檢查時不會報錯,但實際編譯時會出現類似無法 paint 的錯誤。

    其原因是 ListView 的內容項目不固定,導致無法直接放到 Column 底下。解決方法就是在 Column 中放一個能彈性擴展內容的 Expanded,再把 ListView 放到裡面即可。

  • Flutter 在 import 專案自身的 dart 檔案時要務必留意路徑的判定

    Flutter 在 import 專案自身的 dart 檔案時要務必留意路徑的判定

    Flutter 在路徑的解讀上,”/”代表專案的根目錄,如 “/media”就代表專案根目錄下的 media資料夾;而在使用相對路徑時,是以程式 .dart 檔案所在位置做為根目錄。

    在 import 專案自身 .dart 檔案的部分,除了可以使用標準的 package:{專案名稱}/ 寫法外,也可以使用路徑的方式指定。但請只使用相對路徑就好,強烈建議避免如下圖般使用 “/” 根目錄的方式。雖然IDE沒有報錯,但執行時會因為將根目錄判定成專案目錄而不是 “/lib”,造成程式出現錯誤或是神奇現象… 比方說自己遇到的:

    明明透過 Provider 共享的物件有確實先宣告,但後面在用時會一直出現找不到物件的錯誤…這如果只朝編譯器推薦的可能原因去解bug,大概永遠解不了吧 … 暈

  • Flutter provider 中的 read 和 watch 有甚麼差異

    在 Flutter 的 Provider 套件中,read 和 watch 有以下的差異:

    • context.read<T>()
      這個方法會回傳 T 的值,但不會監聽它的變化。也就是說,它只會讀取一次(one-time read)。這個方法不建議在 build() 方法中使用。
    • context.watch<T>()
      這個方法會回傳 T 的值,並且會在值變化時重新構建 widget。也就是說,它會在初次讀取值以及每次值變化時都會讀取(like subscribing to the provider)。

    簡言之,如果需要在值變化時重新構建 widget,使用 watch。如果只需要讀取一次值,並且不需要在值變化時做出反應,使用 read。

  • Flutter 是甚麼??

    Flutter 是甚麼??

    一言以闢之的說就是:用一種程式語言、一個程式架構框架,就能開發對應 Andoird、iOS、Windows、Linux、Web 等平台的 App。只有少數部分的狀況,才需要特別使用各平台對應的程式語言來開發功能。

    詳細介紹

    Flutter 是一個開源的跨平台應用開發框架,由 Google 創建和維護。它可以讓開發者使用一套代碼,快速地創建高性能、美觀、流暢的原生應用,支持 iOS、Android、Windows、Mac、Linux 和 Web 等多種平台。

    Flutter 的核心是一個高效的渲染引擎,基於 Skia 圖形庫,可以直接在畫布上繪製 UI 元素,無需使用原生控件。這樣既減少了與平台的依賴,也提高了 UI 的一致性和自定義性。Flutter 還提供了一套豐富的基礎組件和互動式動畫,讓開發者可以輕鬆地實現各種設計風格和交互效果。

    Flutter 使用 Dart 語言作為開發語言,Dart 是一種面向對象的、類似 Java 的語言,具有優秀的性能和易學易用的特點。Dart 還支持熱重載和熱重啟等功能,讓開發者可以在不停止應用的情況下,即時地修改代碼並查看效果,大大提升了開發效率和體驗。透過成熟而強大的框架,高效且低成本的創建各種類型的應用。

  • Flutter 經典的 StatefulWidget 文字輸入範例

    Flutter 經典的 StatefulWidget 文字輸入範例

    在 Flutter 中,如果要實現一個可以讓使用者輸入文字的元件,我們可以使用 TextField 這個類別。TextField 是一個繼承自 StatefulWidget 的元件,也就是說它有自己的狀態和生命週期。我們可以通過 TextField 的屬性和方法來控制它的外觀和行為。

    main.part

    import 'package:flutter/material.dart';
    
    import 'package:flutter_textinput_example/screens/textinput_screen.dart';

    void main() {
    runApp(const EntryPointApp());
    }

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

    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: 'Flutter TextInput Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    routes: {
    "/task":(BuildContext context) => TextInputScreen(),
    },
    initialRoute: "/task",
    );
    }
    }

    screens/textinput_screen.dart

    import 'package:flutter/material.dart';
    

    // ignore: must_be_immutable
    class TextInputScreen extends StatefulWidget {
    TextInputScreen({super.key});

    List<String> todoList = [];

    @override
    State createState() {
    return _TextInputScreen();
    }
    }

    class _TextInputScreen extends State<TextInputScreen>{
    @override
    Widget build(BuildContext context) {
    var textEditController = TextEditingController();

    Widget userInputTextField = SizedBox(
    width: 500,
    child: TextField(
    decoration: const InputDecoration(
    border: OutlineInputBorder(),
    hintText: '輸入要執行的任務'
    ),
    controller: textEditController,
    onSubmitted: (inputvalue){
    setState(() {
    widget.todoList.add(inputvalue);
    textEditController.clear();
    });
    },
    ),
    );

    return Scaffold(
    body: Container(alignment: Alignment.topCenter,
    child: Column(children: [userInputTextField,
    ...widget.todoList.map((taskString) => Text(taskString)).toList()]),),
    );
    }
    }


  • Flutter 常用元件

    Flutter 常用元件

    • package:flutter/material.dart:最常用的風格元件,外觀為 Android 風格並可適用於 Android 和 iOS 平台。
      • MaterialApp
    • package:http/http.dart:網路存取用的元件。
    • Widget
      • StatelessWidget
      • StatefulWidget
    • Scaffold:最常見的元件,通常用來建立獨立的畫面。
    • Container:容器用途,泛用型。
    • Column:容器用途,裡面的元件為垂直排列。
    • ListView
      • ListTile:ListView裡面的單筆資料列,具有固定的欄位。
    • SingleChildScrollView:讓頁面產生捲動功能。
    • Text:顯示文字。
    • Image:顯示圖檔,來源可以是本地端或是網路。
  • Flutter 世界觀的兩大類 Widget

    Flutter 世界觀的兩大類 Widget

    StatelessWidget

    畫面渲染的時候,直接調度 build 方法。

    StatefulWidget

    畫面渲染的時候,分成兩個類別,一個是 StatefulWidget,一個是專屬於該 StatefulWidget 的 State,透過 State 內的 build 方法,進行畫面渲染。

    下圖為StateFul Widget 的生命週期:

    StateFul Widget Lifecycle
    • initState
      第一次建立元件時觸發,只執行一次。
    • didChangeDependencies
      若有使用 parent 父元件所共享的資料且資料有發生改變時,會觸發此方法。
    • didUpdateWidget
      當 parent 父元件的狀態改變時,會觸發此方法。
    • build
      繪製元件的內容。
    • setState
      重新繪製元件的內容。
    • deactivate
      釋放元件的資源,切換頁面時會觸發該方法。
    • dispose
      關閉元件時觸發該方法。
  • 暫時解決 VSCode Flutter 專案的 Could not create task ‘:generateLockfiles’ 錯誤

    常用外掛 Language Support for Java(TM) by Red Hat 在分析專案中 Java 程式碼的時候,可能會出現以下錯誤:
    The supplied phased action failed with an exception. Could not create task ‘:generateLockfiles’. Process ‘command …..  finished with non-zero exit value 1

    該問題有嘗試過網路上提供的解法包含:使用 Android Studio 開啟專案並循覽到 gradle 目錄、執行 flutter clean & flutter pub cache repair 等,但仍然無法解決。

    因此,就只能夠用最後一個方法 … 停用 Language Support for Java(TM) by Red Hat 外掛~

  • 解決 VSCode Flutter 專案對於 build.gradle 的 Java 11 錯誤

    解決 VSCode Flutter 專案對於 build.gradle 的 Java 11 錯誤

    常用外掛 Language Support for Java(TM) by Red Hat 在分析專案中 Java 程式碼的時候,可能會出現 android/app/build.gradle 檔案使用的 Java 版本錯誤的錯誤訊息,即便已經有安裝最新版本的 Oracle Java 1.8 仍然會報錯。

    解決方法就是在 Java 版本,只要安裝最新版的 OpenJDK 即可。下載 Microsoft 編譯的 OpenJDK,並在安裝的時候勾選”Set JAVA_HOME variable”,讓其成為預設的 Java 版本。
    (不需要移除已經安裝的 Oracle Java)

    android/app/build.gradle 的錯誤訊息

    Could not run phased build action using connection to Gradle distribution 'https://services.gradle.org/distributions/gradle-7.5-all.zip'. org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'android'. A problem occurred configuring root project 'android'. A problem occurred evaluating root project 'android'. A problem occurred configuring project ':app'. Build file 'C:\Documents\FlutterProject\my_home_page\android\app\build.gradle' line: 2 An exception occurred applying plugin request [id: 'com.android.application'] Failed to apply plugin 'com.android.internal.application'. Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8. Your current JDK is located in C:\Program Files\Java\jre-1.8 You can try some of the following options: - changing the IDE settings. - changing the JAVA_HOME environment variable. - changing `org.gradle.java.home` in `gradle.properties`.Java(0) Could not run phased build action using connection to Gradle distribution 'https://services.gradle.org/distributions/gradle-7.5-all.zip'. org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'android'. A problem occurred configuring root project 'android'. A problem occurred evaluating root project 'android'. A problem occurred configuring project ':app'. Build file 'C:\Documents\FlutterProject\my_home_page\android\app\build.gradle' line: 2 An exception occurred applying plugin request [id: 'com.android.application'] Failed to apply plugin 'com.android.internal.application'. Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8. Your current JDK is located in C:\Program Files\Java\jre-1.8 You can try some of the following options: - changing the IDE settings. - changing the JAVA_HOME environment variable. - changing `org.gradle.java.home` in `gradle.properties`.Java(0)