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

Flutter:Alert Dialog内Switch组件动画不显示的问题解决

问题

在Alert Dialog中添加Switch组件后,点击Switch能正常修改全局布尔值bulb(首页背景色会随之切换),但Switch自身的切换动画不会立即生效,必须关闭并重新打开Alert Dialog才能看到状态变化。尝试用StatefulBuilder包裹Switch后,动画正常了,但全局的bulb值又无法同步更新。目前用Shared Preferences存储这个需要全局共享的布尔值。

原代码

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage();

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool bulb = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: bulb ? Colors.white : Colors.blue,
      appBar: AppBar(actions: <Widget>[
        IconButton(
            icon: Icon(Icons.settings),
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (ctx) => AlertDialog(
                          content: Column(children: [
                        Switch(
                          value: bulb,
                          onChanged: (bool isChecked) async {
                            final prefs = await SharedPreferences.getInstance();
                            setState(() {
                              bulb = isChecked;
                              prefs.setBool('bulb', isChecked);
                            });
                          },
                        ),
                        StatefulBuilder(builder:
                            (BuildContext context, StateSetter setState) {
                          return Column(children: [
                            Switch(
                              value: bulb,
                              onChanged: (bool isChecked) async {
                                final prefs =
                                    await SharedPreferences.getInstance();
                                setState(() {
                                  bulb = isChecked;
                                  prefs.setBool('bulb', isChecked);
                                });
                              },
                            ),
                          ]);
                        })
                      ])));
            })
      ]),
      body: Center(),
    );
  }
}
解决方案

问题核心在于:直接用页面的setState无法触发Alert Dialog内部的UI更新;而StatefulBuilder内部的setState作用域只限于对话框,无法同步更新页面状态。

修正方案是将整个Alert Dialog用StatefulBuilder包裹,同时在对话框关闭后调用页面的setState确保页面状态同步:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage();

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool bulb = false;
  
  Future openDialog() => showDialog(
      context: context,
      builder: (context) => StatefulBuilder(
          builder: (context, setState) => AlertDialog(
                  content: Column(children: [
                Switch(
                  value: bulb,
                  onChanged: (bool isChecked) async {
                    final prefs = await SharedPreferences.getInstance();
                    setState(() {
                      bulb = isChecked;
                      prefs.setBool('bulb', isChecked);
                    });
                  },
                ),
                ElevatedButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: Text("Save")),
              ]))));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: bulb ? Colors.white : Colors.blue,
      appBar: AppBar(actions: <Widget>[
        IconButton(
            icon: Icon(Icons.settings),
            onPressed: () async {
              await openDialog();
              setState(() {});
            }),
      ]),
      body: Center(),
    );
  }
}

关键改动说明

  1. 将Alert Dialog封装为独立方法openDialog,并用StatefulBuilder包裹整个对话框,确保对话框内部的setState能触发Switch的动画更新。
  2. 在对话框关闭后,调用页面的setState,确保首页背景色等依赖bulb的UI元素能同步更新。
  3. 添加"Save"按钮用于关闭对话框,让状态更新流程更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:55:37