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

如何修改initState中Widget变量状态,实现AnimatedAlign动画切换?

问题原因与解决方案

问题根源

你在initState中提前构建了包含AnimatedAlign的Widget并存储在Map里,这些Widget的alignment属性在初始化时就绑定了当时的selected初始值(false)。后续调用setState修改selected时,Map里的Widget不会重新构建,因此AnimatedAlign无法感知到selected的变化,动画自然不会触发。

修复方案

不要在initState中预构建Widget实例,改为存储Widget的生成逻辑,在每次渲染时动态生成Widget,确保读取最新的selected值。

修改后的完整代码

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

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  // 存储Widget生成函数,而非预构建的Widget实例
  late Map<String, Map<String, List<Widget Function()>>> dataGenerator;

  bool selected = false;

  @override
  void initState() {
    super.initState();
    dataGenerator = {
      "Animation and motion widgets": {
        "AnimatedAlign": [
          () => GestureDetector(
                onTap: () {
                  setState(() {
                    selected = !selected;
                  });
                  log('$selected inside data');
                },
                child: Center(
                  child: Container(
                    width: 250.0,
                    height: 250.0,
                    color: Colors.red,
                    child: AnimatedAlign(
                      alignment: selected ? Alignment.topRight : Alignment.bottomLeft,
                      duration: const Duration(seconds: 1),
                      curve: Curves.easeInCirc,
                      child: const FlutterLogo(size: 50.0),
                    ),
                  ),
                ),
              )
        ],
      },
      "Animation and motion widgets2": {
        "2widget1": [() => const Text('2widget1')],
        "2widget2": [() => const Text('2widget2')]
      }
    };
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Widget catalog'),
      ),
      body: PageView(
        children: _getCategories(),
      ),
    );
  }

  List<Widget> _getCategories() {
    List<Widget> categories = [];

    for (int i = 0; i < dataGenerator.length; i++) {
      categories.add(
        PageView(
          scrollDirection: Axis.vertical,
          children: getWidgets(i),
        ),
      );
    }
    return categories;
  }

  List<Widget> getWidgets(i) {
    List<Widget> widgetPage = [];
    widgetPage.add(Container(
      color: Colors.red,
      child: Center(
        child: Text(dataGenerator.keys.toList()[i]),
      ),
    ));
    dataGenerator[dataGenerator.keys.toList()[i]]!.forEach((key, value) {
      widgetPage.add(Container(
        color: Colors.blue,
        child: Padding(
          padding: const EdgeInsets.only(top: 20.0),
          child: Column(
            children: [
              Center(child: Text(key)),
              Padding(
                padding: const EdgeInsets.all(20.0),
                // 调用生成函数,获取最新状态的Widget
                child: Column(
                  children: value.map((widgetFunc) => widgetFunc()).toList(),
                ),
              ),
            ],
          ),
        ),
      ));
    });
    return widgetPage;
  }
}

关键改动说明

  1. 数据结构调整:将原data改为dataGenerator,存储返回Widget的函数Widget Function(),而非提前构建好的Widget实例,确保每次渲染都能生成最新状态的Widget。
  2. 动态生成Widget:在getWidgets方法中,通过value.map((widgetFunc) => widgetFunc()).toList()调用生成函数,触发Widget的重新构建,此时AnimatedAlign会读取最新的selected值,动画即可正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:40:24