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

Flutter点击提交问卷按钮添加Linear Progress Indicator及无survey_kit问卷方案咨询

Flutter调查问卷功能实现方案

一、现有survey_kit代码改造(实现提交后跳转动画进度页需求)

修改步骤:

  1. 删除原代码中task.addNavigationRule相关的导航规则,避免拦截提交后的跳转逻辑
  2. 修改SurveyKit组件的onResult回调,触发页面跳转
  3. 新增带动画的进度展示页面,同时包含圆形、线性进度指示器和百分比动画
// 替换原SurveyKit的onResult回调逻辑
onResult: (SurveyResult result) {
  // 提交问卷后直接跳转到动画进度页
  Navigator.of(context).push(
    MaterialPageRoute(builder: (context) => const AnimatedProgressPage())
  );
},
// 新增动画进度页代码
class AnimatedProgressPage extends StatefulWidget {
  const AnimatedProgressPage({super.key});

  @override
  State<AnimatedProgressPage> createState() => _AnimatedProgressPageState();
}

class _AnimatedProgressPageState extends State<AnimatedProgressPage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _progressAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 3));
    _progressAnimation = Tween<double>(begin: 0, end: 1).animate(_controller)
      ..addListener(() => setState(() {}));
    // 启动进度动画
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("提交中"), backgroundColor: Colors.cyan),
      body: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 圆形进度指示器
            CircularProgressIndicator(
              value: _progressAnimation.value,
              color: Colors.cyan,
              strokeWidth: 8,
            ),
            const SizedBox(height: 40),
            // 线性进度指示器
            LinearProgressIndicator(
              value: _progressAnimation.value,
              color: Colors.cyan,
              backgroundColor: Colors.cyan.shade100,
              minHeight: 12,
              borderRadius: BorderRadius.circular(6),
            ),
            const SizedBox(height: 30),
            // 动画百分比文本
            Text(
              "${(_progressAnimation.value * 100).toInt()}%",
              style: const TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.cyan),
            )
          ],
        ),
      ),
    );
  }
}

二、不使用survey_kit包的更优实现方案

方案优势:

  • 灵活度更高:完全自定义UI、交互逻辑,不受第三方包的功能限制
  • 包体积更小:无冗余依赖,减少安装包大小
  • 维护成本更低:代码完全可控,出现问题不需要排查第三方包源码

核心实现思路:

  1. 自定义问卷数据模型,适配不同题型(单选、多选、填空等)
  2. 用IndexedStack/PageView管理问卷步骤,通过状态管理工具统一维护当前步骤、用户答案
  3. 自主实现表单校验、答案存储、提交逻辑,扩展性更强

核心代码示例:

// 1. 问卷步骤通用模型
class SurveyStep {
  final String title;
  final String content;
  final List<String>? options;
  SurveyStep({required this.title, required this.content, this.options});
}

// 2. 自定义问卷主页面
class CustomSurveyPage extends StatefulWidget {
  const CustomSurveyPage({super.key});
  @override
  State<CustomSurveyPage> createState() => _CustomSurveyPageState();
}

class _CustomSurveyPageState extends State<CustomSurveyPage> {
  int currentStep = 0;
  // 问卷步骤配置,可根据需求扩展
  final List<SurveyStep> steps = [
    SurveyStep(title: "尊敬的用户,您好!", content: "请完成以下简短问卷,点击开始按钮答题", options: ["开始答题"]),
    SurveyStep(title: "问题1/7", content: "您最常使用的寄件类型是?", options: ["信件", "包裹", "大件寄件", "以上都不是"]),
    SurveyStep(title: "问题2/7", content: "您是否认可常用寄件类型的定价?", options: ["是", "否", "不确定"]),
    // 剩余问题按上述格式补充即可
    SurveyStep(title: "调研完成", content: "感谢您的参与,点击提交完成问卷", options: ["提交问卷"]),
  ];
  final Map<int, String> userAnswers = {};

  @override
  Widget build(BuildContext context) {
    final step = steps[currentStep];
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 60),
            Text(step.title, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black87)),
            const SizedBox(height: 20),
            Text(step.content, style: const TextStyle(fontSize: 16, color: Colors.black54)),
            const SizedBox(height: 40),
            // 选项渲染
            ...step.options!.map((option) => GestureDetector(
              onTap: () {
                if(currentStep == 0) {
                  setState(() => currentStep++);
                } else if(currentStep == steps.length - 1) {
                  // 提交问卷跳转进度页
                  Navigator.of(context).push(MaterialPageRoute(builder: (context) => const AnimatedProgressPage()));
                } else {
                  userAnswers[currentStep] = option;
                  setState(() => currentStep++);
                }
              },
              child: Container(
                width: double.infinity,
                margin: const EdgeInsets.only(bottom: 12),
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.cyan),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Text(option, style: const TextStyle(fontSize: 15)),
              ),
            ))
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Steph 12222

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:54:04