從建立flutter APP開始。
- 下載SDK
- 安裝 Intellij IDEA 或 Visual Studio
- 設定環境變數
export PATH=`pwd`/flutter/bin:$PATH
4.環境檢測
$ flutter doctor -v
5.新增一個flutter APP,可以選要用什麼語言建立專案。
$ flutter create -i swift -a kotlin myapp$ cd myapp
$ flutter run
6.不時更新一下
$ flutter upgrade
7. 如果需要時變更channel
$ flutter channel dev
8.取得package
$ flutter packages get
9.更新package
$ flutter packages upgrade
運行模式
A.production生產模式 → 優化速度,忽略斷點和靜態類別
B.checked檢查模式 → 在運行時捕獲型別錯誤和異常
APP 圖示變更
直接把原生的app icon替換掉就萬事ok了!這種和原生有關的事我都建議用原生IDE開。
Android路徑:
/android/app/src/main/res/mipmap-/ic_launcher.png
iOS路徑:
Assets.xcassets/AppIcon.appiconset
多國語系
這內容有點多,用另一篇文章寫。
啟動頁(splash screen)
Flutter已經有預設的啟動頁面,把圖片放進去就會自動顯示在啟動頁中心。
Android路徑:
把圖片放進mipmap後,在launch_background.xml指定圖片。
iOS路徑:
用Xcode打開Assets.xcassets,把圖片拉進LaunchImage.imageset。
新增圖片
- 依照比例將圖片放進跟lib 同層自訂的資料夾(ex images)
2. 在pubspec.yaml新增圖片資源
assets:- images/member_1.png- images/member_2.svg
png能直接顯示。
Image.asset("images/member_1.png",height: 30.0, width: 30.0)
svg圖片目前無法用Image顯示,要用套件。
import ‘package:flutter_svg/flutter_svg.dart’;
SvgPicture.asset("images/member_2.svg", height: 30.0, width: 30.0)
常用組件Widget
StatefulWidget:可改變狀態的元件
StatelessWidget:不可改變狀態的元件
- Text
Text('文字內容', textAlign: TextAlign.center, //文字置中 maxLines: 1, //最大行數 overflow: TextOverflow.ellipsis, //文本溢出後顯示省略號 style: const TextStyle( color: Colors.red, decoration: TextDecoration.underline, //下底線 fontWeight: FontWeight.normal, fontSize: 13.0))
2. Image
// 本地圖片Image.asset("images/member_1.png", height: 30.0, width: 30.0)// 網路圖片Image.network('http://xxxx/xxx.jpg',scale:1.0)
重要的來了,每個前端都會遇到的圖片縮放屬性 fit:
BoxFit.fill:不在乎比例拉伸填滿父容器,圖片會變形
BoxFit.contain:原比例
BoxFit.cover:填滿父容器,拉伸或裁切且不會變形
BoxFit.fitWidth:寬度填滿
BoxFit.fitHeight :高度填滿
BoxFit.scaleDown:原比例顯示但不會超過原始圖片大小,會縮小不會放大。
Image.asset( "images/member.png", color: Colors.blue, //混合模式的背景顏色 colorBlendMode: BlendMode.darken, //混合模式 repeat: ImageRepeat.repeat, //垂直和水平重複)
3. Button
RaisedButton
RaisedButton(child: Text('登入'),color: Colors.blue, //按鈕顏色textColor: Colors.white, //字的顏色shape: //圓角 RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),onPressed: () { print('點擊');},)
4. Container
Container( margin: const EdgeInsets.all(10.0), //外邊距 padding: const EdgeInsets.fromLTRB(10.0, 0, 10.0, 0), //內邊距 width: 200, height: 200, alignment: Alignment.centerRight, //內容物靠右垂直置中 // color: Colors.teal, //填滿的顏色 child: Text('text'), // decoration和不可以和color屬性同時使用會衝突 decoration: BoxDecoration( gradient: const LinearGradient(colors: [ Colors.blue, Colors.green ], //漸層背景色 border:Border.all(width:2.0, color:Colors.black), ), //邊框)
常見Layout
1.ListView
body: ListView( scrollDirection: Axis.vertical, //預設是垂直滾動列表 children: <Widget>[ ListTile( title: Text('項目1'), ), ListTile( title: Text('項目2'), ) ],),
列表資料來源可以使用ListView.builder()生成動態列表。
final List<String> items = ['item1', 'item2'];body: new ListView.builder(
itemCount:items.length,
itemBuilder:(context,index){
return new ListTile(
title:new Text('${items[index]}'),
);
}
)
2. GridView
body: GridView.count( padding: const EdgeInsets.all(10.0), crossAxisSpacing: 10.0, //每格之間的間距 crossAxisCount: 3, //每行的格數 childAspectRatio: 2, //寬高比 children: <Widget>[ const Text('1 x 1'), const Text('1 x 2'), const Text('1 x 3'), const Text('2 x 1'), const Text('2 x 2'), const Text('2 x 3'), const Text('3 x 1'), const Text('3 x 2'), const Text('3 x 3') ],),
3. Row 是水平的依序排列(就像一般的紅綠燈)🚥
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 24,
width: 24,
color: Colors.red,
),
Container(
height: 24,
width: 24,
color: Colors.yellow,
),
Container(
height: 24,
width: 24,
color: Colors.green,
),
],
);
4. Column 是垂直的依序排列(拿三色丸子來比喻應該很貼切)🍡
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 24,
width: 24,
color: Colors.red,
),
Container(
height: 24,
width: 24,
color: Colors.white,
),
Container(
height: 24,
width: 24,
color: Colors.green,
),
],
);
訪問權限
flutter沒有public
、protected
、private
,如果一個標識符以下劃線(_)開頭,則它的庫是私有的。
頁面跳轉
一般的push和pop,直接把頁面new出來就能跳轉了。
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
);Navigator.pop(context);
也可以在MyApp的MaterialApp中編寫routes,使用名稱進行navigator routes跳轉。
return MaterialApp(//頁面跳轉路徑routes: <String, WidgetBuilder>{'/homePage': (BuildContext context) => MyHomePage(),'/page2': (BuildContext context) => Page2(),},
Navigator.pushNamed(context, '/page2');
替換頁面堆疊最上層的頁面:
//將堆疊中最上層的那頁替用新的頁面換掉,執行進入動畫Navigator.pushReplacementNamed(context, '/page2');
//將堆疊中最上層的那頁用新的頁面替換掉,執行退出動畫Navigator.popAndPushNamed(context, '/page2');