# 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 模板美化 ---- ![image](https://hackmd.io/_uploads/Skmp3Odjke.png) ---- **常用屬性:** - `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')), ), ), ``` ---- ![image](https://hackmd.io/_uploads/SkcXpOdj1x.png) ---- ## 按鈕元件 ---- ### 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 的圖片 ![image](https://hackmd.io/_uploads/B1bqqKcAke.png) ---- ### IconButton(圖示按鈕) **常用屬性:** - `icon`:顯示的圖示 - `onPressed`:點擊事件處理函式 - `color`:圖示顏色 - `tooltip`:長按提示文字 ```dart IconButton( icon: Icon(Icons.favorite), onPressed: () { print('圖示按鈕被點擊'); }, color: Colors.red, tooltip: '收藏', ) ``` --- ## 佈局元件 ---- ### Container(容器) ---- ![image](https://hackmd.io/_uploads/rkx57kojJl.png) ---- **常用屬性:** - `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`:子元件列表 ---- ![image](https://hackmd.io/_uploads/HJZ4mkooJx.png) ---- ```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(堆疊) ---- 想做出這種效果 ? ![image](https://hackmd.io/_uploads/SkqZE1sjJe.png) ---- **常用屬性:** - `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 ---- 建立可滾動的二為布局陣列 ![image](https://hackmd.io/_uploads/SJCcxesj1g.png) ---- **常用屬性:** - `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}]"}
    358 views
   owned this note