flutter学习三:实现登录界面,登录成功后跳转到首页,从我的界面退出登录
程序员文章站
2022-05-06 16:11:48
...
效果图依次如下:
一步一步摸索、查找资源,最后实现登录界面,登录成功后跳转到首页,从我的界面退出登录,代码有相关的注释,完整代码如下:
1.main.dar
import 'package:flutter/material.dart';
import 'package:flutter_app/screen/Home.dart';
import 'package:flutter_app/screen/LoginScreen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
routes: {//命名导航路由,
'/': (BuildContext context) => new LoginScreen(),
'/Home': (BuildContext context) => new Home(),
'/login': (BuildContext context) => new LoginScreen()
},
}
}
2.1 LoginScreen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class LoginScreen extends StatefulWidget {
@override
State<LoginScreen> createState() {
return new _LoginScreenState();
}
}
class _LoginScreenState extends State<LoginScreen> {
static bool _accountState, _passwordState = false; //用于登录时判断输入的账号、密码是否符合要求
static String _checkHint; //提示语
static TextEditingController _accountController = new TextEditingController();
static TextEditingController _passwordController =
new TextEditingController();
static BuildContext context1;
//校验账号是否符合条件
static void _checkAccount() {
//校验账号不为空且长度大于7(自定义校验条件)
if (_accountController.text.isNotEmpty &&
_accountController.text.trim().length > 7) {
_accountState = true;
} else {
_accountState = false;
}
}
//校验密码是否符合条件
static void _checkPassword() {
//校验密码不为空且长度大于8小于等于15(自定义校验条件)
if (_passwordController.text.isNotEmpty &&
_passwordController.text.length > 8 &&
_passwordController.text.length <= 15) {
_passwordState = true;
} else {
_passwordState = false;
}
}
//账号输入框样式
static Widget buildAccountTextFied(TextEditingController controller) {
/**
*需要定制一下某些颜色时返回Theme,不需要时返回TextField(如后面的密码)
* 修改输入框颜色:没有获取焦点时为hintColor,获取焦点后为:primaryColor
*/
return Theme(
data: new ThemeData(
primaryColor: Colors.amber, hintColor: Colors.greenAccent),
child: new TextField(
controller: controller,
//最大长度
maxLength: 30,
//颜色跟hintColor
//最大行数
maxLines: 1,
//是否自动更正
autocorrect: true,
//是否自动化对焦
autofocus: false,
//是否是密码格式(输入的内容不可见)
obscureText: false,
//文本对齐方式
textAlign: TextAlign.start,
//输入文本的样式
style: TextStyle(fontSize: 20, color: Colors.black),
//允许输入的格式(digitsOnly数字)
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
//内容改变回调
onChanged: (account) {
print('change $account');
},
onSubmitted: (account) {
print('submit $account');
},
//是否禁用
enabled: true,
decoration: InputDecoration(
fillColor: Colors.blue[50],
//底色
filled: true,
//有聚焦,labelText就会缩小到输入框左上角,颜色primaryColor,没聚焦前颜色跟hintColor
labelText: '账号',
//聚焦时才显示,颜色跟hintColor
hintText: '请输入账号',
//红色
// errorText: '输入错误',
//红色,现在在输入框的左下角,跟errorText位置一样(优先显示errorText)
// helperText: 'acount',
//有聚焦,颜色跟primaryColor
prefixIcon: Icon(Icons.person),
//有聚焦显示颜色跟hintColor,显示在输入框的右边
// suffixText: '右边',
contentPadding: EdgeInsets.all(5),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(21.11), //边框裁剪成11.11°角
borderSide: BorderSide(
color: Colors.black,
width: 25.0), //边框颜色、大小没有效果,所以使用返回的是Theme,
)),
),
);
}
//密码输入框样式
static Widget buildPasswordTextFied(TextEditingController controller) {
return TextField(
controller: controller,
//最大长度
maxLength: 30,
//颜色跟hintColor
//最大行数
maxLines: 1,
//是否自动更正
autocorrect: true,
//是否自动化对焦
autofocus: false,
//是否是密码格式(输入的内容不可见)
obscureText: true,
//文本对齐方式
textAlign: TextAlign.start,
//输入文本的样式
style: TextStyle(fontSize: 20, color: Colors.black),
//允许输入的格式(digitsOnly数字)
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
//内容改变回调
onChanged: (password) {
print('change $password');
},
onSubmitted: (password) {
print('submit $password');
},
//是否禁用
enabled: true,
decoration: InputDecoration(
fillColor: Colors.blue[50],
//底色
filled: true,
//输入聚焦以后,labelText就会缩小到输入框左上角,红色,没聚焦前颜色跟hintColor
labelText: '密码',
//聚焦时才显示,颜色跟hintColor
hintText: '请输入密码',
//红色
// errorText: '输入错误',
//红色,现在在输入框的左下角,跟errorText位置一样(优先显示errorText)
// helperText: 'acount',
//输入聚焦时,颜色跟primaryColor
prefixIcon: Icon(Icons.lock),
//聚焦时才显示颜色跟hintColor,显示在输入框的右边
// suffixText: '右边',
contentPadding: EdgeInsets.all(5),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(21.11), //边框裁剪成11.11°角
borderSide: BorderSide(
color: Colors.black, width: 25.0), //没有效果,想要修改就返回Theme(如前面账号样式)
)),
);
}
Widget textSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Column(
mainAxisSize: MainAxisSize.max,
//MainAxisAlignment:主轴方向上的对齐方式,会对child的位置起作用
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildAccountTextFied(_accountController),
buildPasswordTextFied(_passwordController),
],
),
);
Widget loginButton = new Container(
margin: const EdgeInsets.only(left: 35, right: 35),
child: new SizedBox(
//用来设置宽高,如直接使用RaisedButton则不能设置
height: 50,
child: new RaisedButton(
color: Colors.red,
child: new Text(
'登录',
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
_checkAccount();
_checkPassword();
if (_accountState) {
if (_passwordState) {
_checkHint =
'恭喜账号:' + _accountController.text.toString() + "登录成功";
} else {
_checkHint = '请输入8~15位密码!';
}
} else {
_checkHint = '请输入不低于7位账号!';
}
showDialog(
context: context1,
barrierDismissible: true, //点击弹窗外部是否消失
child: new AlertDialog(
title: new Text(
'提示',
style:
new TextStyle(color: Colors.red[300], fontSize: 18),
),
content: new Text(_checkHint),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context1).pop();
},
child: Text('取消')),
new FlatButton(
//对话框按钮
onPressed: () {
if (_accountState && _passwordState) {
Navigator.pushNamed(
context1, '/Home'); //跳转到main.dart命名路由对应的界面
} else {
Navigator.of(context1).pop();
}
},
child: Text('确定')),
],
),
);
})));
@override
Widget build(BuildContext context) {
context1 = context;
return Scaffold(
appBar: new AppBar(
title: new Text('登录'),
),
body: new ListView(
children: [
new Image.asset(
'images/lake.jpg',
width: 600,
height: 240,
//cover(充满容器)、fill(充满父容器)、contain(总有宽或高跟父一样)、none(原图居中显示)、fitWidth(宽度跟父一样)、fitHeight(高度跟父一样)
fit: BoxFit.contain,
),
textSection,
loginButton,
],
));
}
}
2.2图片资源的添加
- 根目录建立images文件夹,把准备好的lake.jpg图片放进去,如下图
- pubspec.yaml,增加的图片资源,需要加进去,如下:
flutter: assets: - images/lake.jpg
3.Home.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/screen/HomePage.dart';
import 'package:flutter_app/screen/MineScreen.dart';
class Home extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _HomeState();
}
}
class _HomeState extends State<Home> {
int _currentIndex = 0;
final List<Widget> _children = [
new HomeScreen(),//首页界面
new MineScreen(),//我的界面
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentIndex],
bottomNavigationBar: new BottomNavigationBar(
onTap: onTabTapped, //点击切换
currentIndex: _currentIndex,
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('首页'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.person),
title: new Text('我的'),
),
],
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
4.HomeScreen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Center(
child: new Text(
'我是Home界面',
style: TextStyle(color: Colors.red, fontSize: 20),
)
),
);
}
}
5.MineScreen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MineScreen extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('我的'),
),
body: new Center(
child: new RaisedButton(
child: new Text('退出登录'),
onPressed: () {
Navigator.of(context).pushNamed('/login');//跳转到main.dart命名路由对应的界面
}),
),
);
}
}
上一篇:flutter学习二:亲测实现官网构建布局第一个例子完整代码
上一篇: python定向爬虫——爬取某代理Ip网站上的所有ip
下一篇: 通过segue切换视图控制器