Web page address: Web page demo
(the web page is slower)
Reference: Original
1. Create a project
flutter create example008_login
2. AS opens
Three. Add dependencies, put in resource files
assets:
- assets/images/logo.png
Four. Writing code
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage()
);
}
}
class LoginPage extends StatefulWidget
{
@override
_LoginPageState createState() {
return _LoginPageState();
}
}
class _LoginPageState extends State<LoginPage>
{
// 用户名输入控制器
TextEditingController _useNameController = TextEditingController();
// 焦点
FocusNode _focusNodeUsername = FocusNode();
FocusNode _focusNodePassword = FocusNode();
// 表单状态
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// 是否显示清除按钮
bool _isShowClear = false;
// 是否显示密码
bool _isShowPwd = false;
// 用户名密码
String _username;
String _password;
// 插入到渲染树时初始化方法
@override
void initState() {
// 添加焦点监听
_focusNodeUsername.addListener(_focusNodeListener);
_focusNodePassword.addListener(_focusNodeListener);
_focusNodeUsername.addListener(()
{
print("用户名:"+_useNameController.text);
_isShowClear = _useNameController.text.isNotEmpty;
print("_isShowClear:"+_isShowClear.toString());
setState(() {
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
// 返回按钮
Widget backImageArea = Container(
height: 45,
alignment: Alignment.centerLeft,
margin: EdgeInsets.only(left: 0),
child: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
print("返回~");
},
),
);
// Logo
Widget logoImageAraa = Container(
margin: EdgeInsets.only(top: 20),
alignment: Alignment.topCenter,
child: Image.asset(
"assets/images/logo.png",
width: 226,
height: 130,
),
);
// 输入框
Widget inputTextArea = Container(
margin: EdgeInsets.only(left: 20,right: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: Colors.white
),
child: Form(
key:_formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _useNameController,
focusNode: _focusNodeUsername,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "用户名",
hintText: "请输入用户名或邮箱或电话号码",
prefixIcon: Icon(Icons.person),
suffixIcon: (_isShowClear)
?IconButton(icon: Icon(Icons.clear), onPressed: (){
_useNameController.clear();
}):null),
validator: validateUserName,
onSaved: (String value){
_username = value;
},
),
TextFormField(
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
labelText: "密码",
hintText: "请输入密码",
prefixIcon: Icon(Icons.lock),
suffixIcon: IconButton(
icon:Icon(_isShowPwd?Icons.visibility:Icons.visibility_off),
onPressed: (){
setState(() {
_isShowPwd=!_isShowPwd;
});
}),
),
obscureText: !_isShowPwd,
validator: validatePassWord,
onSaved: (String value){
_password = value;
},
)
],
),
),
);
// 忘记密码
Widget forgetPwdArea = Container(
margin: EdgeInsets.only(right: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
child: Text(
"忘记密码?",
style: TextStyle(color: Colors.black54),
),
onPressed: () {
print('找回密码');
})
],
),
);
// 登录按钮区域
Widget loginButtonArea = Container(
margin: EdgeInsets.only(left: 20, right: 20),
height: 45,
child: RaisedButton(
color: Colors.blue[500],
child: Text(
"登录",
style: TextStyle(color: Colors.white),
),
// 设置圆角
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
onPressed: () {
// 点击登录按钮,解除焦点,回收键盘
_focusNodeUsername.unfocus();
_focusNodePassword.unfocus();
if (_formKey.currentState.validate()) {
// 输入验证通过
_formKey.currentState.save();
// todo 等录接口相关操作
print("登陆------");
}
}),
);
return Scaffold(
backgroundColor: Colors.white,
body: ListView(
children: <Widget>[
backImageArea,
logoImageAraa,
SizedBox(height: 60,),
inputTextArea,
forgetPwdArea,
SizedBox(height: 14,),
loginButtonArea,
],
),
);
}
// 销毁
@override
void dispose()
{
_focusNodeUsername.removeListener(_focusNodeListener);
_focusNodePassword.removeListener(_focusNodeListener);
_useNameController.dispose();
super.dispose();
}
// 验证用户名
String validateUserName(String value) {
// 验证手机号
if (value.isEmpty) {
return "用户名不能为空!";
} else {
return null;
}
}
// 验证密码
String validatePassWord(String pwd) {
// 正则验证密码
RegExp exp = RegExp("[a-zA-Z0-9_]{6,20}");
if (pwd.isEmpty) {
return "密码不能为空";
} else if (!exp.hasMatch(pwd)) {
return "请输入正确的6-20位数字、字母或下划线的密码";
} else {
return null;
}
}
_focusNodeListener() async
{
print("_focusNodeListener()");
if(_focusNodeUsername.hasFocus)
{
print("用户名框获得焦点");
}
if(_focusNodePassword.hasFocus)
{
print("密码框获得焦点");
}
}
}
5. Debugging and running
Open the Android or iOS simulator in AS first, and click the run button.
Or run in the command line:
flutter run
6. Package the web
flutter build web
Source code
https://gitee.com/ruik2080/example-flutter