iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Mobile Development

畢業專題拯救計畫系列 第 7

Flutter中的資訊系統--狀態管理基本概念

  • 分享至 

  • xImage
  •  

今天我們要介紹的是 Flutter 中的狀態管理。它關係到如何有效地管理和處理應用程式中的數據變化,以及如何根據這些變化來更新 UI。

  • 為什麼狀態管理很重要?
    在 Flutter 中,UI 是由一個個 widget 所組成的,這些 widget 通常會根據應用程式的狀態進行繪製。當應用程式的狀態(如數據、用戶交互等)發生變化時,需要更新對應的 widget 來反映這些變化。狀態管理就是這個過程的核心。

而在第3天中我們有介紹過 StatelessWidget 和 StatefulWidget,我們知道了 StatelessWidget 是靜態的,因此今天所有的狀態管理都是寫在 StatefulWidget 之中。

以下是幾種常見的狀態管理方法:

setState

setState 主要是更新 widget 的狀態,並使得 UI 重新建構。這是因為 Flutter 是一個聲明式框架,你需要告訴框架什麼時候應該重新繪製界面。通常在需要更改頁面內容時使用,例如按鈕點擊、表單提交或計時器等等。

int counter = 0;

void incrementCounter() {
  setState(() {
    counter++;
  });
}

InheritedWidget

InheritedWidget 是 Flutter 中的一種特殊的 widget,用於在 widget 中共享和傳遞狀態。它主要用於在 widget 中向下傳遞數據,讓子 widget 能夠更快的使用這些數據,藉此提高性能。
InheritedWidget 允許將狀態或數據從一個 widget 傳遞到 widget 樹中的其他 widget。這樣,任何需要這些數據的子 widget 都可以方便地訪問它們。

import 'package:flutter/material.dart';

// 自定義 InheritedWidget
class MyInheritedWidget extends InheritedWidget {
  final int data;

  MyInheritedWidget({required this.data, required Widget child}) : super(child: child);

  // 靜態方法來獲取 MyInheritedWidget 實例
  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    return data != (oldWidget as MyInheritedWidget).data;
  }
}

// 使用 InheritedWidget 的範例
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final myData = MyInheritedWidget.of(context)?.data;

    return Center(
      child: Text('Data: $myData'),
    );
  }
}

Provider

Provider 是 Flutter 中的一個常用狀態管理解決方案,並提供了簡單的 API 來進行依賴注入、狀態管理和通知。比直接使用 InheritedWidget 來的簡便。

  • 首先,需要在 pubspec.yaml 文件中 dependencies 新增 provider 。
dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0
  • 創建一個用來管理狀態的類,這個類通常會繼承自 ChangeNotifier,並提供更新狀態的方法。
import 'package:flutter/material.dart';

class Counter with ChangeNotifier {
 int _count = 0;

 int get count => _count;

 void increment() {
   _count++;
   notifyListeners();
 }
}
  • 使用 ChangeNotifierProvider 將狀態提供給 widget 樹中的子 widget。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
 runApp(
   ChangeNotifierProvider(
     create: (context) => Counter(),
     child: MyApp(),
   ),
 );
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: HomeScreen(),
   );
 }
}
  • 使用 Consumer 或 Provider.of 方法在 widget 中訪問和顯示狀態。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Provider Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<Counter>(
              builder: (context, counter, child) {
                return Text(
                  'Count: ${counter.count}',
                  style: TextStyle(fontSize: 24),
                );
              },
            ),
            ElevatedButton(
              onPressed: () {
                Provider.of<Counter>(context, listen: false).increment();
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

我們明天見~


上一篇
Flutter中的導航--Navigator 和 Routes
下一篇
Flutter中的訂單系統--API基本概念
系列文
畢業專題拯救計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言