登錄界面設計
在手機App的開發過程中,基本App都會有登錄界面,所以我們今天將使用Flutter來實現登錄界面的效果。
首先,我們需要掌握登錄界面有那些元素,比如用戶名,密碼提示以及輸入框,其次可能還有上面的logo,下面的登錄按鈕,以及忘記密碼等顯示。
前面博主講解組件的時候,已經講過,在Flutter開發中,一切皆組件,也就是說,你可以把界面直接賦值給一個變量,比如前面的操作,那麼多return代碼,可以直接複製給一個變量,這樣方便插入操作,那麼多嵌套的寫着,要是弄丟一個括號,估計找就得找死,所以賦值變量,然後放置在return中,代碼看起來就會簡潔很多。
login_page.dart登錄頁面代碼
這裏我們先寫登錄頁面,login_page.dart代碼如下:
import 'package:flutter/material.dart';
import 'home_page.dart';
//登錄界面
class LoginPage extends StatefulWidget {
static String tag = 'login-page';
@override
_LoginPageState createState() => new _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
final logo = Hero(//飛行動畫
tag: 'hero',
child: CircleAvatar(//圓形圖片組件
backgroundColor: Colors.transparent,//透明
radius: 48.0,//半徑
child: Image.asset("assets/logo.png"),//圖片
),
);
final email = TextFormField(//用戶名
keyboardType: TextInputType.emailAddress,
autofocus: false,//是否自動對焦
initialValue: '[email protected]',//默認輸入的類容
decoration: InputDecoration(
hintText: '請輸入用戶名',//提示內容
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),//上下左右邊距設置
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)//設置圓角大小
)
),
);
final password = TextFormField(//密碼
autofocus: false,
initialValue: 'ssssssssssssssssssssss',
obscureText: true,
decoration: InputDecoration(
hintText: '請輸入密碼',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
)
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),//上下各添加16像素補白
child: Material(
borderRadius: BorderRadius.circular(30.0),// 圓角度
shadowColor: Colors.lightBlueAccent.shade100,//陰影顏色
elevation: 5.0,//浮動的距離
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
onPressed: (){
Navigator.of(context).pushNamed(HomePage.tag);//點擊跳轉界面
},
color: Colors.green,//按鈕顏色
child: Text('登 錄', style: TextStyle(color: Colors.white, fontSize: 20.0),),
),
),
);
final forgotLabel = FlatButton(//扁平化的按鈕,前面博主已經講解過
child: Text('忘記密碼?', style: TextStyle(color: Colors.black54, fontSize: 18.0),),
onPressed: () {},
);
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(//將這些組件全部放置在ListView中
shrinkWrap: true,//內容適配
padding: EdgeInsets.only(left: 24.0, right: 24.0),//左右填充24個像素塊
children: <Widget>[
logo,
SizedBox(height: 48.0,),//用來設置兩個控件之間的間距
email,
SizedBox(height: 8.0,),
password,
SizedBox(height: 24.0,),
loginButton,
forgotLabel
],
),
),
);
}
}
home_page.dart主頁面代碼
上面註釋已經非常詳細了,這裏就不在贅述,細心的讀者應該看到這段代碼中有一個登錄按鈕,點擊之後的跳轉界面,也就是大多數App的首頁,所以我們還需要寫一個跳轉之後的界面home_page.dart,代碼如下:
import 'package:flutter/material.dart';
//登錄後的主界面
class HomePage extends StatelessWidget{
static String tag="home_page";
@override
Widget build(BuildContext context) {
final user=Hero(
tag: "用戶名",
child: Padding(
padding: EdgeInsets.all(20.0),//所有方向均填充20像素空白
child: CircleAvatar(
radius: 72.0,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage("assets/timg.jpg"),
),
),
);
final welcome=Padding(//歡迎文字提示
padding: EdgeInsets.all(8.0),
child: Text(
'歡迎你',
style: new TextStyle(color: Colors.white, fontSize: 20.0),
),
);
final info=Padding(//其他文字提示
padding: EdgeInsets.all(8.0),
child: Text(
"登錄界面就是這麼簡單簡單哦!",
style: new TextStyle(color: Colors.white, fontSize: 20.0),
),
);
final body=Container(//body主要內容
width: MediaQuery.of(context).size.width,//設置爲屏幕寬度
padding: EdgeInsets.all(28.0),//上下左右各填充28空白像素
decoration: BoxDecoration(//裝飾器,博主前面的漸變色介紹過
gradient: LinearGradient(//線性漸變
colors: [
Colors.green,//藍
Colors.lightGreenAccent//綠偏黃的顏色
]
)
),
child: Column(children: <Widget>[//將上面定義的子空間全部添加進去
user, welcome, info,
],),
);
return Scaffold(
body: body,
);
}
}
mian.dart程序入口代碼
這上面的註釋也是非常的詳細,而且線性漸變之前介紹組件的時候有講解過,應該很好理解,兩個界面都寫完了,現在重要的就是App程序入口代碼需要寫,mian.dart代碼如下:
import 'package:flutter/material.dart';
import 'package:login_flutter_app/page/home_page.dart';
import 'package:login_flutter_app/page/login_page.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
//routes需要Map<String, WidgetBuilder>類型參數,所以這裏定義了一個這個類型的常量,將剛纔兩個頁面添加進去
final routes = <String, WidgetBuilder> {
LoginPage.tag: (context) => LoginPage(),
HomePage.tag: (context) => HomePage(),
};
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: '登錄Demo',
debugShowCheckedModeBanner: false,
theme: new ThemeData(
primarySwatch: Colors.lightBlue,
),
home: LoginPage(),
routes: routes,
);
}
}
3個注意事項
這段代碼有幾點需要注意:
第一,我們之前寫的所有應用,是不是右上角都有一個debug標籤呢?這在實際應用中肯定不會要的,所以這裏設置debugShowCheckedModeBanner屬性爲false,就不會顯示debug標籤。
第二,前面我們跳轉頁面用的pop(),然後push(),出棧進棧的方式操作,這裏我們定義了一個路由,將使用到的頁面全部寫在裏面,後續需要使用的時候,只要使用如下代碼就可以直接跳轉:
Navigator.of(context).pushNamed(key);
這就是剛在定義路由routes裏面的key值,這種跳轉屬於靜態路由,前面用到的屬於動態路由,兩種都可以跳轉界面,這裏提及一樣方便大家理解。
第三,home定義App首次進入頁面的主頁面,其中也可以設置initialRoute屬性來達到初始頁面的設置,如果沒有initialRoute這個屬性,那麼會去尋找路由表裏面的’/’,或者MaterialApp的home屬性。但需要特別注意一下,路由表(也就是我們上面代碼裏面定義的routes變量)裏面的’/’(key值) 和MaterialApp的home屬性,二者不能同時存在,但是必須有一個存在。
當initialRoute和’/‘或者MaterialApp的home屬性同時存在的時候,initialRoute的優先級高於二者。意思就是如果initialRoute定義的頁面和’/'或者MaterialApp的home設置的頁面不一樣,用戶看到的是initialRoute定義的頁面。
當MaterialApp的home屬性定義了主頁面,而initialRoute沒有定義的時候,用戶看到的就是’/'或者MaterialApp的home多對應的頁面。
登錄界面的代碼就講到這裏,顯示的效果如博文首圖所示。
該博文代碼的下載地址:點擊下載