大致了解過常用的 widget 後我們可以開始來看看怎麼實作一個比較完整的登入畫面,因為這次的登入只使用到第三方登入所以就不會需要輸入帳號密碼, textview 的部分就不會練習到了,不過後面應該還是會有機會看到的,第三方登入目前選用 FB 登入希望能在在下一篇開始實作。
目前的登入畫面包含
這幾個部分我們可以來大致看看該怎麼做,大家也可以自己實作看看,說不定這樣會有更多收穫
這是我們今天要刻的畫面
需要全螢幕沒有 app bar 所以我就不選用 scaffold 當基本的框架
我們可以看到畫面主要分成兩層,需要有上下層次所以選用 Stack
第一層使用 Image 當作背景圖片,
第二層使用 Column 用來排列標題、按紐
Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(),
Column(
children: <Widget>[],
)
],
);
使用圖片需要先匯入資源檔
flutter:
assets:
- assets/images/whiteCar.jpg
Image.asset(
"assets/images/whiteCar.jpg" ,
fit: BoxFit.fill,
)
補充:
BoxFit 種類
BoxFit.fill 透過寬高比失真來填滿
BoxFit.contain 盡量大但要完全包含
BoxFit.cover 盡量小但要完全覆蓋
BoxFit.fitWidth 符合寬度
BoxFit.fitHeight 符合高度
BoxFit.none 不改變圖片
參考 :https://api.flutter.dev/flutter/painting/BoxFit-class.html
標題包含大標題跟副標題 都是透過 Text 來顯示
Text("熊熊洗車",
style: TextStyle(
color:Colors.black ,
fontSize: 70 ,
fontWeight:FontWeight.bold,
decoration: TextDecoration.none
)
),
Text("bear friends 汽機車修理及清潔",
style: TextStyle(
color:Colors.black ,
fontSize: 20 ,
fontWeight:FontWeight.bold,
decoration: TextDecoration.none
)
),
補充:
不知道為何只要沒有加 decoration: TextDecoration.none 就會產生下底線
有人知道為何會這樣嗎?可以在底下留言告訴我感謝各位。
就是利用上回我們我做的 loginBtn 來使用,還是有做一些修改
class LoginBtn extends StatelessWidget {
const LoginBtn({
Key key,
this.color = const Color(0xFF2DBD3A),
this.child ,
this.onPressed
}) : super(key: key);
final Color color ;
final Widget child ;
final Function() onPressed ;
@override
Widget build(BuildContext context) {
//引入sizeBox 來調整 btn 大小
return SizedBox(
height: 50,
width: MediaQuery.of(context).size.width*0.9,
child:RaisedButton(
color: color,
child: child ,
onPressed: onPressed,
),
);
}
}
//MediaQuery.of(context).size.width 可以取得目前螢幕的寬度
@override
Widget build(BuildContext context) {
final loginBtn = LoginBtn(
onPressed: _login ,
//FB Color
color:Color.fromARGB(255, 66, 103, 178),
child: Text(
"Facebook Login" ,
style: TextStyle(color: Colors.white ,
fontWeight: FontWeight.bold ,
fontSize:18
),
),
) ;
return Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset("assets/images/whiteCar.jpg" , fit: BoxFit.fill,),
Column(
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 50.0)),
Text("熊熊洗車",
style: TextStyle(
color:Colors.black ,
fontSize: 70 ,
fontWeight:FontWeight.bold,
decoration: TextDecoration.none
)
),
Text("bear friends 汽機車修理及清潔",
style: TextStyle(
color:Colors.black ,
fontSize: 20 ,
fontWeight:FontWeight.bold,
decoration: TextDecoration.none
)
),
Spacer(),
loginBtn,
Padding(padding: EdgeInsets.only(top: 50.0)),
],)
],
);
}
//用 Spacer 填滿剩下的空間
這樣應該就能完成一個簡單的登入畫面了,不過需求總是會變動的,如果今天需要增加 Google 登入該怎麼做呢?
大家可以自己嘗試看看喔!
先新增一個 loginGoogleBtn 並放在 loginBtn之下?
final loginGoogleBtn = LoginBtn(
onPressed: _login ,
//FB Color
color:Colors.white,
child: Text(
"Google Login" ,
style: TextStyle(color: Colors.grey ,
fontWeight: FontWeight.bold ,
fontSize:18
),
),
) ;
不過我還想請教在 LoginBtn的Constructor函式中
const LoginBtn({
Key key,
this.color = const Color(0xFF2DBD3A),
this.child ,
this.onPressed
}) : super(key: key);
: super(key: key); 這段是什麼意思?
super(key : key) 的功能是會呼叫父類別的建構子
LoginBtn 繼承了 Staless 所以
會把 key 往上傳遞到 Stataless > Widget 。
一般來說如果父類的建構子沒有傳遞參數,子類在生成的時候就會自動去引用,但是因為這邊需要把 key 傳送到 widget,有傳遞參數就必須去呼叫 super(key : key)。
而 key 的功能可以用來識別是哪個 widget ,如果 element tree 上關聯的 widget 跟新的 widget key 相同的話就會被更新,我們也能透過 key 來在外部改變 widget 的狀態,不過目前應該是用不到。
更詳細的內容可以參考官方的 doc 。
關於 key :https://api.flutter.dev/flutter/foundation/Key-class.html
瞭解~非常謝謝您~
所以換句話說,只要我們不在建構函式中,傳入key的話
就不需要 呼叫 父類的構造函式 super(key:key)