Flutter布局锦囊---男女性别单选

设计给的效果如下:

UI布局图

拿到设计后,先把整体拆分成几个部分:

  1. “点击操作”,感应用户选择性别的区域。
  2. “选择性别男”,性别男的选择区域,点击会更新图片和样式。
  3. “选择性别女”,性别女的选择区域,点击会更新图片和样式。

然后就可以开始进行编码了。

第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),
                ),
              ),
            ],
          ),
        ),

第5步:还原效果

男女性别单选的还原效果