用flutter寫一個精美的登入頁面
阿新 • • 發佈:2019-01-24
先看效果圖;
我們先看一下頁面 , 首先這個頁面,我們並沒有用到AppBar,當然也就沒有自帶返回功能.
然後下面有個Login的文字以及一條橫線.
螢幕中上方是填寫帳號以及密碼的2個輸入框,密碼輸入框有隱藏和顯示密碼的按鈕.
下方是登入按鈕 以及其他登入方式.
看一下主體佈局:
return Scaffold( body: Form( key: _formKey, child: ListView( padding: EdgeInsets.symmetric(horizontal: 22.0), children: <Widget>[ SizedBox( height: kToolbarHeight, ), buildTitle(), buildTitleLine(), SizedBox(height: 70.0), buildEmailTextField(), SizedBox(height: 30.0), buildPasswordTextField(context), buildForgetPasswordText(context), SizedBox(height: 60.0), buildLoginButton(context), SizedBox(height: 30.0), buildOtherLoginText(), buildOtherMethod(context), buildRegisterText(context), ], )));
頁面在一個Scaffold中包裹著, 然後整體佈局是縱向的,於是我們用ListView來做外層控制元件,因為是有輸入框,所以我們又用了Form來包裹住整體.
標題部分
buildTitle(),
buildTitleLine(),
分別實現了Login
的文字元件和下方的一個橫線元件.
Login:
Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Login',
style: TextStyle(fontSize: 42.0),
),
);
橫線:
Padding( padding: EdgeInsets.only(left: 12.0, top: 4.0), child: Align( alignment: Alignment.bottomLeft, child: Container( color: Colors.black, width: 40.0, height: 2.0, ), ), );
可以看到,都是用Padding做外層元件,前者包裹了一個Text,後者包裹了一個Container.
輸入框
TextFormField buildPasswordTextField(BuildContext context) { return TextFormField( onSaved: (String value) => _password = value, obscureText: _isObscure, validator: (String value) { if (value.isEmpty) { return '請輸入密碼'; } }, decoration: InputDecoration( labelText: 'Password', suffixIcon: IconButton( icon: Icon( Icons.remove_red_eye, color: _eyeColor, ), onPressed: () { setState(() { _isObscure = !_isObscure; _eyeColor = _isObscure ? Colors.grey : Theme.of(context).iconTheme.color; }); })), ); } TextFormField buildEmailTextField() { return TextFormField( decoration: InputDecoration( labelText: 'Emall Address', ), validator: (String value) { var emailReg = RegExp( r"[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"); if (!emailReg.hasMatch(value)) { return '請輸入正確的郵箱地址'; } }, onSaved: (String value) => _email = value, ); }
用TextFormField 來實現輸入框, 帳號我們規定是郵箱,所以用了正則表示式來驗證:
var emailReg = RegExp(
r"[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?");
如果不符合,在提交的時候會給出相應的提示.
密碼輸入那裡使用了判空的方法,多了一個顯示/隱藏密碼的按鈕:
decoration: InputDecoration(
labelText: 'Password',
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: _eyeColor,
),
onPressed: () {
setState(() {
_isObscure = !_isObscure;
_eyeColor = _isObscure
? Colors.grey
: Theme.of(context).iconTheme.color;
});
})),
可以看到在decotation中設定,suffixIcon
是在後面加一個圖示,這裡給它一個點選方法是改變是否顯示密碼的,並更改圖示的顏色.
登入
Align buildLoginButton(BuildContext context) {
return Align(
child: SizedBox(
height: 45.0,
width: 270.0,
child: RaisedButton(
child: Text(
'Login',
style: Theme.of(context).primaryTextTheme.headline,
),
color: Colors.black,
onPressed: () {
if (_formKey.currentState.validate()) {
///只有輸入的內容符合要求通過才會到達此處
_formKey.currentState.save();
//TODO 執行登入方法
print('email:$_email , assword:$_password');
}
},
shape: StadiumBorder(side: BorderSide()),
),
),
);
}
登入按鈕,是一個RaiseButton,點選的時候,我們判斷輸入框內容,符合條件會執行登入方法.
其他帳號登入
ButtonBar buildOtherMethod(BuildContext context) {
return ButtonBar(
alignment: MainAxisAlignment.center,
children: _loginMethod
.map((item) => Builder(
builder: (context) {
return IconButton(
icon: Icon(item['icon'],
color: Theme.of(context).iconTheme.color),
onPressed: () {
//TODO : 第三方登入方法
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text("${item['title']}登入"),
action: new SnackBarAction(
label: "取消",
onPressed: () {},
),
));
});
},
))
.toList(),
);
}
其他帳號登入,這裡我以facebook,twitter和google為例來實現的
ButtonBar是一個按鈕的組合,我們放了3個IconButton, 並在list中定義了支援的登入方式. 點選圖示實現對應的登入方法.
其他都是些text使用,跟login大致相同,不再介紹了,想了解請看原始碼.github