點燈坊

失くすものさえない今が強くなるチャンスよ

建立 Stateful 頁面

Sam Xiao's Avatar 2024-09-03

大多數的頁面到需要 State,如經典的 Counter,可簡單地使用 StatefulWidght 實現。

Version

Flutter 3.24
Dart 3.5

Flutter

counter01

  • Android 成功使用 StatefulWidget 實現 counter

Main

main.dart

import 'package:flutter/material.dart';

import 'Counter.dart';

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

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

  
  Widget build(BuildContext context) {
    return const MaterialApp(home: Counter());
  }
}
  • Import 自己建立的 counter.dart
  • 建立 MyApp widget 並傳入 runApp() 顯示在 view

StatefulWidget

Counter.dart

import 'package:flutter/material.dart';

class Counter extends StatefulWidget {
  const Counter({super.key});

  
  State<Counter> createState() {
    return _Counter();
  }
}

class _Counter extends State<Counter> {
  var _count = 0;

  void _onPressed() {
    setState(() => _count++);
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter Demo')),
      floatingActionButton: FloatingActionButton(
          onPressed: _onPressed, child: const Icon(Icons.add)),
      body: Center(child: Text('$_count')),
    );
  }
}
  • Stateful 頁面需由兩個 class 構成
    • StatefulWidget:啟動 State
    • State:實質控制 state 與顯示 UI

Line 3

class Counter extends StatefulWidget {
  const Counter({super.key});

  
  State<Counter> createState() {
    return _Counter();
  }
}
  • 定義 Counter page,繼承自 StatefulWidget class
  • createState() 會轉 _Counter state

Line 12

class _Counter extends State<Counter> {
}
  • 定義 _Counter state class

Counter_ 寫在 後面 會違反 Dart 命名規則

Line 13

var _count = 0;
  • 定義 _count state

Private field 與 private method 在 Dart 的 naming convention 會加上 _

Line 15

void _onPressed() {
  setState(() => _count++);
}
  • 定義 _onPressed() 處理 FloatingActionButtononPressed event
  • setState():寫入 state

Line 19


Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('Counter Demo')),
    floatingActionButton: FloatingActionButton(
      onPressed: _onPressed, child: const Icon(Icons.add)),
    body: Center(child: Text('$_count')),
  );
}
  • 建立 Counter 的 UI

Conclusion

  • 雖然可在 build() 內直接使用 anonymous method 給 onPressed event,但將 method 與 UI 混在一起不容易維護