You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:如何在Icon Stepper中添加TextFormFields输入框?

给Icon Stepper添加TextFormFields实现步骤表单

原代码里的IconStepper仅作为侧边步骤指示器,输入表单需要放在相邻区域,根据当前步骤切换显示内容。下面是修改后的完整实现:

import 'package:flutter/material.dart';
// 确保已引入icon_stepper包
import 'package:icon_stepper/icon_stepper.dart';

// 修正类名首字母大写,符合Dart编码规范
class IconStep extends StatefulWidget {
  const IconStep({Key? key}) : super(key: key);

  @override
  State<IconStep> createState() => _IconStepState();
}

class _IconStepState extends State<IconStep> {
  int stepIndex = 0;
  // 表单全局Key,用于统一验证表单状态
  final _formKey = GlobalKey<FormState>();
  // 每个输入框对应控制器,管理输入内容
  final TextEditingController _taskController = TextEditingController();
  final TextEditingController _busController = TextEditingController();
  final TextEditingController _restaurantController = TextEditingController();
  final TextEditingController _hotelController = TextEditingController();
  final TextEditingController _noteController = TextEditingController();

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    _taskController.dispose();
    _busController.dispose();
    _restaurantController.dispose();
    _hotelController.dispose();
    _noteController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 定义各步骤对应的表单组件
    List<Widget> stepForms = [
      TextFormField(
        controller: _taskController,
        decoration: const InputDecoration(labelText: "填写任务信息"),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return "请输入任务信息";
          }
          return null;
        },
      ),
      TextFormField(
        controller: _busController,
        decoration: const InputDecoration(labelText: "填写交通信息"),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return "请输入交通信息";
          }
          return null;
        },
      ),
      TextFormField(
        controller: _restaurantController,
        decoration: const InputDecoration(labelText: "填写餐饮信息"),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return "请输入餐饮信息";
          }
          return null;
        },
      ),
      TextFormField(
        controller: _hotelController,
        decoration: const InputDecoration(labelText: "填写住宿信息"),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return "请输入住宿信息";
          }
          return null;
        },
      ),
      TextFormField(
        controller: _noteController,
        decoration: const InputDecoration(labelText: "填写备注信息"),
        maxLines: 3,
      ),
    ];

    return Scaffold(
      appBar: AppBar(title: const Text("步骤表单")),
      body: Row(
        children: <Widget>[
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(15.0),
            ),
            child: IconStepper(
              steppingEnabled: true,
              stepRadius: 25.0,
              stepColor: Colors.grey[200]!, // 替换你项目中的kPrimaryLightColor
              direction: Axis.vertical,
              activeStepColor: Colors.blue[100]!, // 替换你项目中的kPrimaryLightColor
              activeStepBorderColor: Colors.white,
              activeStepIndex: stepIndex,
              // 点击步骤时更新当前索引
              onStepReached: (index) {
                setState(() {
                  stepIndex = index;
                });
              },
              icons: const [
                Icon(Icons.task_alt, color: Colors.grey),
                Icon(Icons.directions_bus, color: Colors.grey),
                Icon(Icons.restaurant, color: Colors.grey),
                Icon(Icons.hotel, color: Colors.grey),
                Icon(Icons.note_alt, color: Colors.grey),
              ],
            ),
          ),
          // 右侧表单区域,占满剩余屏幕空间
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(24.0),
              child: Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // 显示当前步骤对应的表单
                    stepForms[stepIndex],
                    const SizedBox(height: 32),
                    // 步骤导航按钮组
                    Row(
                      children: [
                        if (stepIndex > 0)
                          ElevatedButton(
                            onPressed: () {
                              if (_formKey.currentState!.validate()) {
                                setState(() {
                                  stepIndex--;
                                });
                              }
                            },
                            child: const Text("上一步"),
                          ),
                        const Spacer(),
                        if (stepIndex < stepForms.length -1)
                          ElevatedButton(
                            onPressed: () {
                              if (_formKey.currentState!.validate()) {
                                setState(() {
                                  stepIndex++;
                                });
                              }
                            },
                            child: const Text("下一步"),
                          ),
                        if (stepIndex == stepForms.length -1)
                          ElevatedButton(
                            onPressed: () {
                              if (_formKey.currentState!.validate()) {
                                // 这里添加表单提交逻辑
                                ScaffoldMessenger.of(context).showSnackBar(
                                  const SnackBar(content: Text("表单提交成功")),
                                );
                              }
                            },
                            child: const Text("提交"),
                          ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

核心修改说明

  • 给IconStepper绑定activeStepIndex和onStepReached回调,实现步骤切换逻辑
  • 在Row中新增Expanded容器,用来承载对应步骤的TextFormFields
  • 使用Form组件和全局Key管理表单,实现输入合法性验证
  • 为每个输入框添加控制器,单独管理输入内容并在组件销毁时释放资源
  • 增加步骤导航按钮,带表单验证逻辑,确保当前步骤输入合法后再切换

内容的提问来源于stack exchange,提问作者Farhana Akter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:20:32