Flutter布局锦囊---绑定手机页
2019-01-27 本文已影响26人
何小有
设计给的效果如下:
UI布局图拿到设计后,先把整体拆分成几个部分:
- “顶部导航栏”,标题+取消按钮+跳过按钮的应用栏。
- “手机号输入框”,用于获取手机号码的圆角边框输入字段。
- “验证码输入框”,用于获取验证码的圆角边框输入字段,还包括获取验证码的按钮。
- “提交按钮”,在满足条件后让用户点击的提交按钮。
然后就可以开始进行编码了。
第1步:绘制组件树
绑定手机页的组件树第2步:实现“顶部导航栏”
下面的代码导入了一堆东西,大概说一下都是些什么吧。../common/first_navigation.dart
是《Flutter布局锦囊---简单的应用栏》,不过针对这个需求做了一些小改动。../common/doodle_button.dart
是《Flutter布局锦囊---涂鸦风格按钮》。../common/round_form_field.dart
是《Flutter布局锦囊---圆框的表单字段》。widgets/login_form_code.dart
是《Flutter布局锦囊---验证码倒计时》。
import 'package:flutter/material.dart';
import '../common/first_navigation.dart';
import '../common/doodle_button.dart';
import '../common/round_form_field.dart';
import 'widgets/login_form_code.dart';
/// 自定义的绑定页面组件。
class Binding extends StatefulWidget {
@override
_BindingState createState() => _BindingState();
}
下面代码的主体是《Flutter布局锦囊---简单的应用栏》中自定义的一级导航(firstNavigation
)组件,不过这里你要把行动(actions
)和主导(leading
)属性设置成可以配置的,如果没有则为空值(null
)。
/// 与自定义的绑定页面组件关联的状态子类。
class _BindingState extends State<Binding> {
/// 手机号表单字段的控制器。
final _phoneController = TextEditingController();
/// 验证码表单字段的控制器。
final _codeController = TextEditingController();
/// 发送验证码按钮是否可用。
bool _codeAvailable = false;
/// 手机号表单字段是否符合格式。
bool _phoneActivation = false;
/// 验证码表单字段是否符合格式。
bool _codeActivation = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: firstNavigation(
'绑定手机',
// 墨水瓶(`InkWell`)组件,响应触摸的矩形区域。
leading: InkWell(
child: Text(
' 取消 ',
style: TextStyle(
color: Color(0xFF777777),
fontSize: 16.0,
),
),
onTap: (){
Navigator.of(context).pop();
},
),
actions: InkWell(
child: Text(
' 跳过 ',
style: TextStyle(
color: Color(0xFFFF6B47),
fontSize: 16.0,
),
),
onTap: (){
Navigator.of(context).pushNamedAndRemoveUntil('/', (Route<dynamic> route) => false);
},
),
),
body: ListView(
padding: EdgeInsets.symmetric(horizontal: 20.0),
children: <Widget>[
// TODO: 第3步:实现“手机号输入框”
// TODO: 第4步:实现“验证码输入框”
// TODO: 第5步:实现“提交按钮”
],
),
);
}
}
第3步:实现“手机号输入框”
下面代码的主体是《Flutter布局锦囊---圆框的表单字段》中自定义的圆框表单字段(RoundFormField
)组件。这个就可以直接使用了,不用像上面那一步修改代码。
// TODO: 第3步:实现“手机号输入框”
Container(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: Text(
'绑定手机后可以直接使用手机号码登录',
style: TextStyle(
color: Color(0xFF777777),
fontSize: 14.0,
),
),
),
RoundFormField(
hintText: '请输入手机号',
textEditingController: _phoneController,
checkCallback: (value){
if(value.trim().length == 11) {
_codeAvailable = true;
_phoneActivation = true;
} else {
_codeAvailable = false;
_phoneActivation = false;
}
setState(() {});
},
),
SizedBox(height: 20),
第4步:实现“验证码输入框”
下面代码的主体是《Flutter布局锦囊---圆框的表单字段》中自定义的圆框表单字段(RoundFormField
)组件,再佐以《Flutter布局锦囊---验证码倒计时》中自定义的倒计时(LoginFormCode
)组件作为调料。它们共同完成了验证码输入框。
// TODO: 第4步:实现“验证码输入框”
Stack(
children: <Widget>[
RoundFormField(
hintText: '请输入验证码',
textEditingController: _codeController,
checkCallback: (value){
if(value.trim().length == 6) {
_codeActivation = true;
} else {
_codeActivation = false;
}
setState(() {});
},
),
// 对齐(`Align`)组件,用于将其子项与其自身对齐,并根据子级的大小自行调整大小。
Align(
// 高度因子(`heightFactor`)属性,如果为非空值,则将其高度设置为子组件高度乘以此系数。
heightFactor: 2.0,
// 对准(`alignment`)属性,如何调整子组件。
alignment: Alignment.centerRight,
child: LoginFormCode(
countdown: 60,
available: _codeAvailable,
onTapCallback: () {
// 根据需求写提交的过程以及后续操作~
},
),
),
],
),
第5步:实现“提交按钮”
下面代码的主体是《Flutter布局锦囊---涂鸦风格按钮》中自定义的涂鸦按钮(DoodleButton
)组件,注意要通过setState(() {});
来改变按钮的可点击状态。
// TODO: 第5步:实现“提交按钮”
SizedBox(height: 40),
DoodleButton(
promptText: '绑定',
activation: _phoneActivation && _codeActivation,
onTapCallback: (){
setState(() {
_codeActivation = false;
});
// 根据需求写提交的过程以及后续操作~
setState(() {
_codeActivation = true;
});
},
),