Flutter 入门与实战(九):开发一个常用的登录页面

  • decoration:文本框的装饰,属性也很多,可以指定前置图标,边框类型、后置组件等多种属性,因此可以通过 decoration 获得想要的文本框样式。
  • focusNode:聚焦点,可以通过这个来控制文本框是否获取焦点,从而实现类似上一个下一个的输入控制。
  • onChanged:输入值改变事件回调,通常用这个方法实现双向绑定。

在这个案例中,我们使用了一个前置图标用来表示输入内容的类型,比如使用手机图标代表输入手机号,使用锁代表代表密码。同时使用了一个 Offstage作为后置的组件,用于在输入内容后可以点击清除内容。Offstage 组件是通过一个属性offstage来控制组件是否显示,这样我们可以在没有内容的时候隐藏它,有输入内容的时候再显示。

为了提高代码复用性,使用了一个方法获取通用的文本框,这里主要是使用了 Container包裹以控制边距和文本框下的分隔线:

Widget _getInputTextField(
TextInputType keyboardType, {
FocusNode focusNode,
controller: TextEditingController,
onChanged: Function,
InputDecoration decoration,
bool obscureText = false,
height = 50.0,
}) {
return Container(
height: height,
margin: EdgeInsets.all(10.0),
child: Column(
children: [
TextField(
keyboardType: keyboardType,
focusNode: focusNode,
obscureText: obscureText,
controller: controller,
decoration: decoration,
onChanged: onChanged,
),
Divider(
height: 1.0,
color: Colors.grey[400],
),
],
),
);
}

完整代码

class _LoginPageState extends State {
//TextEditingController可以使用 text 属性指定初始值
TextEditingController _usernameController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
String _username = ‘’, _password = ‘’;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(‘登录’),
brightness: Brightness.dark,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_getRoundImage(‘images/logo.png’, 100.0),
SizedBox(
height: 60,
),
_getUsernameInput(),
_getPasswordInput(),
SizedBox(
height: 10,
),
_getLoginButton(),
],
),
),
);
}

Widget _getUsernameInput() {
return _getInputTextField(
TextInputType.number,
controller: _usernameController,
decoration: InputDecoration(
hintText: “输入手机号”,
icon: Icon(
Icons.mobile_friendly_rounded,
size: 20.0,
),
border: InputBorder.none,
//使用 GestureDetector 实现手势识别
suffixIcon: GestureDetector(
child: Offstage(
child: Icon(Icons.clear),
offstage: _username == ‘’,
),
//点击清除文本框内容
onTap: () {
this.setState(() {
_username = ‘’;
_usernameController.clear();
});
},
),
),
//使用 onChanged 完成双向绑定
onChanged: (value) {
this.setState(() {
_username = value;
});
},
);
}

Widget _getPasswordInput() {
return _getInputTextField(
TextInputType.text,
obscureText: true,
controller: _passwordController,
decoration: InputDecoration(
hintText: “输入密码”,
icon: Icon(
Icons.lock_open,
size: 20.0,
),
suffixIcon: GestureDetector(
child: Offstage(
child: Icon(Icons.clear),
offstage: _password == ‘’,
),
onTap: () {
this.setState(() {
_password = ‘’;
_passwordController.clear();
});
},
),
border: InputBorder.none,
),
onChanged: (value) {
this.setState(() {
_password = value;
});
},
);
}

//省略了上述列举的代码

}

页面跳转

在上层面的登录按钮上,我们增加了一个点击事件,点击后再跳到登录页,按钮的响应代码如下所示。这是页面跳转的最简单的方式,使用 Navigator 导航器的 push方法实现页面跳转,后续会介绍如何通过路由实现页面跳转,那种方式更为优雅。
//…
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => LoginPage()),
);
},
//…

总结

从代码上看,功能虽然实现了,但是构建用户名和密码的代码十分相似,有没有办法进一步提高代码复用率,构建一个更为通用的表单组件呢?下篇我们将介绍如何来封装。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

文末

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

这里笔者分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【视频教程】

天道酬勤,只要你想,大厂offer并不是遥不可及!希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

-RkAYZyvr-1712616504240)]

天道酬勤,只要你想,大厂offer并不是遥不可及!希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的Flutter登录页面的示例: ```dart import 'package:flutter/material.dart'; class LoginPage extends StatefulWidget { @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'Welcome to My App', style: TextStyle(fontSize: 24.0), ), SizedBox(height: 32.0), Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: TextField( controller: _usernameController, decoration: InputDecoration( hintText: 'Username', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), ), ), ), ), SizedBox(height: 16.0), Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: TextField( controller: _passwordController, decoration: InputDecoration( hintText: 'Password', border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), ), ), obscureText: true, ), ), SizedBox(height: 32.0), RaisedButton( onPressed: () { // Here's where you would handle the login logic final String username = _usernameController.text.trim(); final String password = _passwordController.text.trim(); print('Username: $username'); print('Password: $password'); }, child: Text('Log In'), ), ], ), ), ); } } ``` 该页面包含一个具有用于键入用户名和密码的文本字段的表单,以及一个登录按钮。当用户点击登录按钮时,您可以在`onPressed`方法中处理登录逻辑,并检查用户名和密码是否正确,或者在后端执行实际的身份验证操作。在此示例中,我们只是将用户名和密码打印到控制台上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值