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

Flutter中Scaffold.showSnackBar不显示问题求助

Flutter SnackBar 不显示问题排查与修复

问题根源

你的页面根组件使用的是Material,而ScaffoldMessenger需要依托Scaffold提供的上下文才能正常工作。没有Scaffold的情况下,当前context无法找到对应的ScaffoldMessenger实例,导致showSnackBar调用后没有任何视觉反馈,虽然print能正常输出。

修复方案

将页面根组件替换为Scaffold,Scaffold内部会自动集成ScaffoldMessenger,确保SnackBar能正常显示。同时修正一些代码规范和逻辑细节:

  1. 替换根组件为Scaffold,将背景色设置到Scaffold的backgroundColor属性
  2. 规范State类命名(符合Flutter大驼峰命名约定)
  3. 修正setState的语法错误
  4. 优化本地加载年龄后的有效性标记逻辑

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen1.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen3.dart';

class Screen2 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => Screen2State();
}

class Screen2State extends State<Screen2> {
  void returnScreen(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        fullscreenDialog: true,
        builder: (context) => Screen1(),
      ),
    );
  }

  @override
  void initState() {
    loadData();
    super.initState();
  }

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

  int age = 10;
  bool nextValid = false;

  void toast(String text) {
    print(text);
    final scaffold = ScaffoldMessenger.of(context);
    scaffold.showSnackBar(
      SnackBar(
        content: Text(text),
        behavior: SnackBarBehavior.floating,
      ),
    );
  }

  void submitData() async {
    if (!nextValid) {
      toast('Please input your age');
      return;
    }
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt('age', age);
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        fullscreenDialog: true,
        builder: (context) => SingleSelectListViewWithLogo(items: [
          'Tone Up - You want visible muscles with as little mass as possible and a low body fat percentage',
          'Bulk Up - You want large, defined muscles, with a low percentage of body fat',
          'Get Jacked - You want to lift an insane amount of weight and don\'t care about body fat or muscle definition'
        ]),
      ),
    );
  }

  void loadData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    try {
      int? x = prefs.getInt('age');
      print(x);
      if (x != null) {
        setState(() => age = x);
        setState(() => nextValid = true);
      }
    } catch (e) {
      print('Load age error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      backgroundColor: Colors.grey,
      body: Stack(
        children: <Widget>[
          Positioned(
            top: size.height * .06,
            left: size.width * .03,
            child: InkWell(
              onTap: () {
                returnScreen(context);
              },
              child: Image.asset(
                alignment: Alignment.topLeft,
                "assets/images/back2.png",
                width: size.width * .07,
              ),
            ),
          ),
          Positioned(
              top: size.height * .09,
              left: size.width * .42,
              child: const Text(
                style: TextStyle(fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                'Next,'
              )
          ),
          Positioned(
            top: size.height * .15,
            left: size.width * .16,
            child: const Text(
              style: TextStyle(fontSize: 20, color: Color.fromARGB(255, 76, 74, 74)),
              'Lets customize your workout!'
            ),
          ),
          Positioned (
            top: size.height * .23,
            left: size.width * .28,
            child: Image.asset(
              "assets/images/age.png",
              width: size.width * .4
            )
          ),
          Positioned(
            top: size.height * .55,
            left: size.width * .15,
            child: const Text(
              style: TextStyle(fontSize: 25, color: Color.fromARGB(255, 21, 17, 17)),
              'What\'s your current age?'
            ),
          ),
          Positioned (
            top: size.height * .7,
            left: size.width * .1,
            child: SliderTheme(
              data: const SliderThemeData(
                trackHeight: 30,
                inactiveTrackColor: Color.fromARGB(255, 255, 255, 255),
                activeTrackColor: Color.fromARGB(255, 50, 45, 45),
                thumbColor: Colors.black,
                disabledActiveTrackColor: Colors.black,
                disabledInactiveTrackColor: Colors.black12,
                thumbShape: RoundSliderThumbShape(enabledThumbRadius: 25.0),
              ),
              child: SizedBox(
                width: size.width * .8,
                child: Slider(
                  label: "Select Age",
                  value: age.toDouble(),
                  onChanged: (value) {
                    setState(() {
                      age = value.toInt();
                      nextValid = true;
                    });
                  },
                  min: 10,
                  max: 99,
                ),
              ),
            ),
          ),
          Positioned (
            top: size.height * .62,
            left: size.width * .28,
            child: Text(
              age.toString(),
              style: const TextStyle(
                fontSize: 40.0,
              ),
            ),
          ),
          Positioned (
            top: size.height * .64,
            left: size.width * .42,
            child: const Text (
              'years old',
              style: TextStyle(
                fontSize: 25.0,
              ),
            ),
          ),
          Positioned(
            top: size.height * .86,
            left: size.width * .1,
            child: SizedBox(
              width: size.width * .8,
              height: size.height * .08,
              child: ElevatedButton(
                style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all<Color>(!nextValid ? const Color.fromRGBO(69, 75, 85, 1) : const Color.fromARGB(255, 0, 147, 246)),
                ),
                child: const Text('Continue',
                  style: TextStyle(fontSize: 20),
                ),
                onPressed: submitData,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

额外说明

  • 添加SnackBarBehavior.floating属性,避免SnackBar被底部按钮遮挡
  • 修正类名的大驼峰命名,符合Dart/Flutter编码规范
  • 在loadData中加载到本地年龄后,自动标记为有效状态,减少用户重复操作
  • 简化了按钮点击事件的调用方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:24:59