如何修改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; } }
关键改动说明
- 数据结构调整:将原
data改为dataGenerator,存储返回Widget的函数Widget Function(),而非提前构建好的Widget实例,确保每次渲染都能生成最新状态的Widget。 - 动态生成Widget:在
getWidgets方法中,通过value.map((widgetFunc) => widgetFunc()).toList()调用生成函数,触发Widget的重新构建,此时AnimatedAlign会读取最新的selected值,动画即可正常生效。
内容的提问来源于stack exchange,提问作者Logan
相关产品推荐
相关产品推荐

