Flutter 學習筆記

最後更新日期:2023 年 8 月 26 日。

快捷鍵

Control+J:快速文件查閱。

Scaffold

移除 DEBUG 標籤:加入「debugShowCheckedModeBanner: false,」。

MaterialApp(
  home: Scaffold(
    appBar: AppBar(title: const Text('My App')),
    body: const Text('Hello World'),
  ),
),

Stateless/Stateful Widget

Hot Reload (重跑 build method) 在 Stateless/ful Widget 中才會啟用。

setState(() {
  
});

App Icon

iOSApp Icon Generator → iPhone & iPad → 更換 ios/Runner/Assets.xcassets 資料夾。
Android:右鍵 Project → Flutter → Open Android module in Android Studio → 右鍵 res → New → Image Asset。

SafeArea

Alt+Enter → Wrap with widget… → 命名為 SafeArea。

Container

只能有一個 child。
沒有 child 時盡可能無限大,有 child 時根據其大小調整。
技巧:width: double.infinity,

Column/Row

mainAxisSize: MainAxisSize.min, //因為預設會無限大
verticalDirection: VerticalDirection.up, //顛倒方向開始

mainAxisAlignment: MainAxisAlignment.____,
(1) center/end //更改顯示位置
(2) spaceBetween //頭尾無間距
(3) spaceEvenly //頭尾有間距

crossAxisAlignment: CrossAxisAlignment.____,
(1) end
(2) stretch

Margin(外)/Padding(內)

EdgeInsets.all(10.0),
EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), //對稱
EdgeInsets.fromLTRB(10.0, 20.0, 30.0, 40.0), //left,top,right,bottom
EdgeInsets.only(left: 10.0),

SizedBox

SizedBox(height: 10.0),

Network/Asset Image

Image.asset:在 Project 下建立「images」資料夾,在 pubspec.yaml 中,找到「assets:」按下「Ctrl + /」來取消註解,改成「- images/」來讀取整個資料夾的內容,最後再「Pub get」。

Image.network('https://url.com/cat.jpg'),
Image.asset('images/cat.jpg'),

NetworkImage('https://url.com/cat.jpg'),
AssetImage('images/cat.jpg'),

CircleAvatar

CircleAvatar(
  radius: 50.0,
  backgroundImage: AssetImage('images/avatar.jpg'),
),

Fonts

在 Project 下建立「fonts」資料夾,放入字體檔,更新 pubspec.yaml。

  fonts:
    - family: Noto Serif TC
      fonts:
        - asset: fonts/NotoSerifTC-ExtraLight.otf
          weight: 200
        - asset: fonts/NotoSerifTC-Light.otf
          weight: 300
        - asset: fonts/NotoSerifTC-Regular.otf
          weight: 400
        - asset: fonts/NotoSerifTC-Medium.otf
          weight: 500
        - asset: fonts/NotoSerifTC-SemiBold.otf
          weight: 600
        - asset: fonts/NotoSerifTC-Bold.otf
          weight: 700
        - asset: fonts/NotoSerifTC-Black.otf
          weight: 900
Text(
  '哈囉',
  style: TextStyle(
    fontFamily: 'Noto Serif TC',
    fontWeight: FontWeight.w900,
  ),
),

Card

Card:帶有圓角和陰影的面板。

Card(
  child: const Padding(
    padding: EdgeInsets.all(8.0),
    child: Text('Card'),
  ),
),

ListTile

ListTile:一個有 leading、title、subtitle、trailing 的 Row。

ListTile(
  leading: const Icon(Icons.history),
  title: const Text('板橋大遠百'),
  subtitle: const Text('220新北市板橋區新站路28號'),
  trailing: const Icon(Icons.favorite),
  tileColor: Colors.grey[200],
),

Divider

Divider(
  height: 20.0, //上下間距
  thickness: 3.0, //粗度
  indent: 150.0, //左間距
  endIndent: 150.0, //右間距
  color: Colors.teal,
),

Expanded

Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(...),
    ),
    Expanded(
      child: Container(...),
    ),
  ],
),

TextButton

自帶 left: 16.0, right: 16.0 的 padding。

TextButton(
  style: TextButton.styleFrom(
    backgroundColor: Colors.teal,
    foregroundColor: Colors.white,
  ),
  onPressed: () {},
  child: const Text('TextButton'),
),

Random

import 'dart:math';
Random().nextInt(max); //0~max-1

List

List<Widget> myList = [];
myList.add(...);
myList.insert(2, ...);

Class & Constructor

在 lib 資料夾中新增「xxx.dart」當作 Class。

class Drink {
  String name = '未命名的飲料';
  int price = 0;

  // Drink(this.name, this.price);

  Drink(String n, int p) {
    name = n;
    price = p;
  }

  String info() {
    return '【$name】$price 元';
  }
}
import 'xxx.dart';
Drink d1 = Drink('珍珠奶茶', 55);
Text(d1.info()),

Private

在變數名稱前面加上 _。
用處:Encapsulation (封裝),更安全。
將所有地方的某個變數變成 Private:對變數右鍵 → Refactor → Rename。

Inheritance (繼承)

class B extends A

Polymorphism

@override same function (at A) when you extends from A
(can use “super.func()” to use old func in new func, even the name is same as func)

this

void main() {
  User andy = User(age: 18);
  print(andy.age);
}

class User {
  int age = 0;

  // User({required this.age});

  User({required int age}) {
    this.age = age;
  }
}

Set Background Image (BoxDecoration)

In a container.

decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('images/background.png'),
            fit: BoxFit.cover,
          ),
        ),

Visibility

Warp with widget, and rename to “Visibility”.
visible: bool(ture or false).

floatingActionButton

floatingActionButton: FloatingActionButton(
  onPressed: () {},
  child: const Icon(Icons.add),
),

Theme

MaterialApp(
  theme: ThemeData.dark(),
);
發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *