# Flutter UI
# 之
# 簡易再簡易介紹
---
小複習 :
Widget(元件) 是Flutter應用程式使用者介面的基本建構區塊。
---
想了解更多Widget ?
或者看到一個Widget卻不知道怎麼用 ?
* https://api.flutter.dev/flutter/widgets/
* https://docs.flutter.dev/ui/widgets
---
Flutter 的設計模型基於以下幾個重要概念 :
1. 約束傳遞 : 父Widget向子Widget傳遞約束條件。
2. 大小確定 : 子Widget在這些約束條件下確定自己的大小
3. 位置確定 : 父Widget根據自身大小和子Widget的大小,確定子Widget的位置。
---
## Scaffold 與其子元件
----
### Scaffold
----
**常用屬性:**
- `appBar`:應用欄
- `body`:主要內容
- `bottomNavigationBar`:底部導航
- `floatingActionButton`:浮動按鈕
- `drawer`:側邊欄
-
以上輸入的都是Widget喔
----
### AppBar
**常用屬性:**
- `title`:標題
- `leading`:左側元件
- `actions`:右側動作按鈕
- `elevation`:陰影高度
- `backgroundColor`:背景顏色
----
### Drawer
**常用屬性:**
- `child`:抽屜內容
- `elevation`:陰影高度
- `backgroundColor`:背景顏色
----
### BottomNavigationBar
**常用屬性:**
- `items`:導航項目列表
- `currentIndex`:當前選中的項目索引
- `onTap`:項目被點擊時的回調函式
- `backgroundColor`:背景顏色
----
### TabBar & TabBarView
需搭配 DefaultTabController 使用
**常用屬性:**
- `tabs`:頁籤列表
- `controller`:頁籤控制器
- `children`:對應頁籤的內容列表
----
### FloatingActionButton(浮動按鈕)
**常用屬性:**
- `onPressed`:點擊事件處理函式
- `child`:按鈕內容 (通常是圖示)
- `backgroundColor`:背景顏色
- `tooltip`:長按提示文字
---
## UI 元件 篇
----
### Text
顯示文字
----
先來看一眼 Constructor(建構子)
```
Text(String data, {
Key? key,
TextStyle? style,
StrutStyle? strutStyle,
TextAlign? textAlign,
TextDirection? textDirection,
Locale? locale,
bool? softWrap,
TextOverflow? overflow,
@Deprecated('Use textScaler instead. ' 'Use of textScaleFactor was deprecated in preparation for the upcoming nonlinear text scaling support. ' 'This feature was deprecated after v3.12.0-2.0.pre.') double? textScaleFactor,
TextScaler? textScaler,
int? maxLines,
String? semanticsLabel,
TextWidthBasis? textWidthBasis,
TextHeightBehavior? textHeightBehavior,
Color? selectionColor})
```
嗯...應該是最後一眼了
----
**常用屬性:**
- `data`:顯示的文字內容
- `style`:文字樣式,搭配 TextStyle 使用
- `maxLines`: 限定文字顯示的最大行數
- `overflow`: 設定超出版面的效果顯示(搭配maxLines屬性)
- `textAlign`: 設定文字對齊方式,如 TextAlign.center
- `textDirection`: 設定文字方向,如 TextDirection.rtl (右到左)
----
舉例
```dart
Text(
'Hello, Flutter!',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
)
```
----
### TextStyle
----
**常用屬性:**
- `fontSize`:字體大小
- `fontWeight`:字體粗細,如 FontWeight.bold
- `color`:文字顏色
- `fontFamily`:字體家族
- `fontStyle`:字體樣式,如 FontStyle.italic(斜體)
- `letterSpacing`:字母間距
- `wordSpacing`:單字間距
- `height`:行高倍數
- `decoration`:文字裝飾,如 TextDecoration.underline(底線)
- `shadows`:文字陰影
----
```dart
Text(
'TextStyle 範例',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
color: Colors.blue,
letterSpacing: 1.5,
height: 1.5,
decoration: TextDecoration.underline,
decorationColor: Colors.red,
decorationThickness: 2.0,
shadows: [
Shadow(
color: Colors.grey,
offset: Offset(2.0, 2.0),
blurRadius: 3.0,
),
],
),
)
```
----
### Image(圖片)
----
**常用屬性:**
- `width`、`height`:設定圖片尺寸
- `fit`:控制圖片如何填充給定的空間,如BoxFit.cover
- `errorBuilder`: 當圖片載入失敗時顯示的內容
- `loadingBuilder`: 當圖片載入中顯示的內容
----
網路載入 :
```dart
Image.network(
'https://example.com/image.png',
width: 100,
height: 100,
fit: BoxFit.cover,
)
```
----
**使用本地 image 的事前準備工作 :**
1. 在package底下建立 `assets` 資料夾
2. 在 pubspec.yaml 檔案中,新增圖片路徑
```
flutter:
assets:
- assets/images/my_image.png //照片路徑
```
3. `flutter pub get`
3. 使用 Image.asset
```dart
Image.asset(
'assets/images/my_image.png',
width: 100,
height: 100,
)
```
----
### Card
模板美化
----

----
**常用屬性:**
- `child`:卡片內部元件
- `elevation`:陰影高度
- `shape`:卡片形狀
- `margin`:外邊距
```dart
Card(
elevation: 4.0,
margin: EdgeInsets.all(10.0),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('Card 內容'),
),
)
```
----
搭配 Inkwell 就可以點選
```dart=
Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
debugPrint('Card tapped.');
},
child: const SizedBox(width: 300, height: 100, child: Text('A card that can be tapped')),
),
),
```
----

----
## 按鈕元件
----
### ElevatedButton(凸起按鈕)
**常用屬性:**
- `onPressed`:點擊事件處理函式
- `child`:按鈕內容
- `style`:按鈕樣式
```dart
ElevatedButton(
onPressed: () {
print('按鈕被點擊');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
child: Text('凸起按鈕'),
)
```
----
### TextButton(文字按鈕)
**常用屬性:**
- `onPressed`:點擊事件處理函式
- `child`:按鈕內容
- `style`:按鈕樣式
```dart
TextButton(
onPressed: () {
print('文字按鈕被點擊');
},
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
),
child: Text('文字按鈕'),
)
```
----
### OutlinedButton(輪廓按鈕)
**常用屬性:**
- `onPressed`:點擊事件處理函式
- `child`:按鈕內容
- `style`:按鈕樣式
```dart
OutlinedButton(
onPressed: () {
print('輪廓按鈕被點擊');
},
style: OutlinedButton.styleFrom(
backgroundColor: Colors.blue,
side: BorderSide(color: Colors.blue),
),
child: Text('輪廓按鈕'),
)
```
----
三種 Button 的圖片

----
### IconButton(圖示按鈕)
**常用屬性:**
- `icon`:顯示的圖示
- `onPressed`:點擊事件處理函式
- `color`:圖示顏色
- `tooltip`:長按提示文字
```dart
IconButton(
icon: Icon(Icons.favorite),
onPressed: () {
print('圖示按鈕被點擊');
},
color: Colors.red,
tooltip: '收藏',
)
```
---
## 佈局元件
----
### Container(容器)
----

----
**常用屬性:**
- `width`、`height`:設定寬度與高度
- `color`:背景顏色
- `child`:內嵌子元件
- `padding`:內邊距
- `margin`:外邊距
- `decoration`:設定邊框、圓角、陰影等
----
使用範例 :
```dart
Container(
width: 200,
height: 100,
padding: EdgeInsets.all(16.0),
margin: EdgeInsets.symmetric(vertical: 8.0),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
),
],
),
child: Center(child: Text('Container')),
)
```
----
### Center
將子元件居中
```dart
Center(
child : Text("Center Text"),
)
```
----
### Row & Column
----
**常用屬性:**
- `mainAxisAlignment`:主軸對齊方式
- `crossAxisAlignment`:次軸對齊方式
- `children`:子元件列表
----

----
```dart
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.star, color: Colors.yellow),
Text('Row Example')
],
)
```
```dart
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Column Item 1'),
Text('Column Item 2')
],
)
```
----
### Stack(堆疊)
----
想做出這種效果 ?

----
**常用屬性:**
- `children`:子元件列表 (後面的元件會覆蓋前面的元件)
- `alignment`:子元件的對齊方式
- `fit`:子元件的大小調整方式
----
```dart
Stack(
alignment: const Alignment.center,
children: [
const CircleAvatar(
backgroundImage: AssetImage('images/pic.jpg'),
radius: 100,
),
Container(
decoration: const BoxDecoration(color: Colors.black45),
child: const Text(
'Mia B',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
)
```
----
### Expanded & Flexible
**常用屬性:**
- `flex`:分配空間的權重比例
- `child`:子元件
```dart
Row(
children: [
Expanded(
flex: 2,
child: Container(color: Colors.red, height: 100),
),
Expanded(
flex: 1,
child: Container(color: Colors.blue, height: 100),
),
],
)
```
----
### GridView
----
建立可滾動的二為布局陣列

----
**常用屬性:**
- `gridDelegate`:設定網格佈局 (如列數、間距等)
- `children`:網格項目
- `itemCount` 與 `itemBuilder`:動態網格項目(搭配 GridView.builder)
```dart
GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
padding: EdgeInsets.all(10.0),
children: List.generate(6, (index) {
return Container(
color: Colors.blue[100 * (index % 9 + 1)],
child: Center(
child: Text('Item $index'),
),
);
}),
)
```
----
### ListView(列表)
**常用屬性:**
- `children`:固定列表項目
- `itemCount` 與 `itemBuilder`:動態列表項目(搭配 ListView.builder)
- `scrollDirection`:滾動方向
- `padding`:內邊距
----
```dart
// 固定列表
ListView(
padding: EdgeInsets.all(8.0),
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
)
// 動態列表
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item ${index + 1}'),
);
},
)
```
---
## 訊息提示窗元件
----
### AlertDialog(警示對話框)
**常用屬性:**
- `title`:標題
- `content`:內容
- `actions`:動作按鈕列表
----
```dart
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('提示'),
content: Text('這是一個警示對話框'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('確定'),
),
],
);
},
);
```
----
### SimpleDialog(簡單對話框)
**常用屬性:**
- `title`:標題
- `children`:對話框選項列表
----
```dart
showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: Text('選擇選項'),
children: [
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '選項 1');
},
child: Text('選項 1'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '選項 2');
},
child: Text('選項 2'),
),
],
);
},
);
```
----
### BottomSheet(底部彈出框)
**常用屬性:**
- `builder`:構建 BottomSheet 內容的函式
- `backgroundColor`:背景顏色
----
```dart
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: 200,
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('底部彈出框標題', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 16),
Text('這是底部彈出框的內容'),
SizedBox(height: 16),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: Text('關閉'),
),
],
),
);
},
);
```
{"title":"Flutter 基礎元件","description":"小複習 :Widget(元件) 是Flutter應用程式使用者介面的基本建構區塊。","contributors":"[{\"id\":\"a4f75e0c-9d89-46ef-bb69-c76e3924561f\",\"add\":10561,\"del\":0},{\"id\":\"03942d1d-4fa2-48ae-a543-59087572dc6e\",\"add\":1,\"del\":0}]"}