设计给的效果如下:
拿到设计后,先把整体拆分成几个部分:
- “点击操作”,感应用户选择性别的区域。
- “选择性别男”,性别男的选择区域,点击会更新图片和样式。
- “选择性别女”,性别女的选择区域,点击会更新图片和样式。
然后就可以开始进行编码了。
第1步:绘制组件树
第2步:实现“点击操作”
首先为性别男和性别女的图文内容搭一个可以点击的区域,等一下把它们俩放在这个区域里来,同时定义一个性别选择的控制器,用来记录用户选择的性别。
import 'package:flutter/material.dart';
/// 自定义的性别选择组件。
class GenderSelection extends StatefulWidget {
/// 选择性别时的回调函数。
final Function selectCallback;
GenderSelection({
this.selectCallback,
});
@override
_GenderSelectionState createState() => _GenderSelectionState();
}
/// 与自定义的性别选择组件关联的状态子类。
class _GenderSelectionState extends State<GenderSelection> {
/// 性别选择的控制器,0表示未选择,1表示男人,2表示女人。
int _genderController = 0;
@override
Widget build(BuildContext context) {
return Row(
// 主轴对齐(`mainAxisAlignment`)属性,如何将子组件放在主轴上。
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// TODO: 第3步:实现“选择性别男”
// TODO: 第4步:实现“选择性别女”
],
);
}
}
第3步:实现“选择性别男”
将性别男的选中、未选中图片和文本说明,来组合一个选择性别男的组件,并结合性别选择的控制器来更新图片和文本。
// TODO: 第3步:实现“选择性别男”
GestureDetector(
onTap: (){
// 选择男人时返回1并更新组件。
setState(() {
_genderController = 1;
widget.selectCallback(_genderController);
});
},
child: Column(
children: <Widget>[
Image.asset(
_genderController == 1
? 'assets/icon_male_selected.png'
: 'assets/icon_male_normal.png',
fit: BoxFit.contain,
height: 90.0,
width: 90.0,
),
Text(
'男',
style: TextStyle(
fontSize: 16.0,
color: _genderController == 1
? Color(0xFF25C6CA)
: Color(0xFF4A4A4A),
),
),
],
),
),
第4步:实现“选择性别女”
与上面选择性别男的组件一样,不过你要在中间插入一个大小框(SizedBox)组件来分离它们,毕竟距离产生美鸭。
// TODO: 第4步:实现“选择性别女”
SizedBox(width: 36.0),
GestureDetector(
onTap: (){
// 选择女人时返回2并更新组件。
setState(() {
_genderController = 2;
widget.selectCallback(_genderController);
});
},
child: Column(
children: <Widget>[
Image.asset(
_genderController == 2
? 'assets/icon_female_selected.png'
: 'assets/icon_female_normal.png',
fit: BoxFit.contain,
height: 90.0,
width: 90.0,
),
Text(
'女',
style: TextStyle(
fontSize: 16.0,
color: _genderController == 2
? Color(0xFFFF6B47)
: Color(0xFF4A4A4A),
),
),
],
),
),