AnimatedSwitcher在ReorderableListView中失效,ListView中正常疑与Key相关
解决AnimatedSwitcher在ReorderableListView中不工作的问题
你遇到的问题确实和Key的使用逻辑有关——ReorderableListView对其子项的Key有特殊要求,而你当前的Key设置方式打断了AnimatedSwitcher的动画触发机制。
问题根源
你给AnimatedSwitcher本身设置了ValueKey(value.i),这意味着每次点击按钮改变数字时,AnimatedSwitcher组件会因为Key变化被Flutter视为一个全新的组件,直接重建而不会执行内部的切换动画。同时,ReorderableListView需要它的直接子项拥有稳定且唯一的Key来跟踪组件身份,随数据变化的Key会干扰这个机制。
修复方案
调整Key的设置逻辑:
- 给
AnimatedSwitcher设置一个固定的Key,确保它在ReorderableListView中的身份始终稳定; - 保留
NumberTile的ValueKey(value.i),让AnimatedSwitcher能检测到子组件的更替,从而触发切换动画。
修改后的代码
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => ChangeNumber(), child: MaterialApp( title: 'Flutter Demo', home: Scaffold( body: SafeArea( child: Consumer<ChangeNumber>( builder: (context, value, child) { return Column( children: <Widget>[ Container( height: 100, child: ReorderableListView( onReorder: (oldIndex, newIndex) {}, children: <Widget>[ AnimatedSwitcher( // 修改:给AnimatedSwitcher设置固定Key key: const Key('animated_switcher'), duration: const Duration(seconds: 1), child: NumberTile( number: value.i, key: ValueKey(value.i), ), ), ], ), ), RaisedButton( child: const Text('Increase'), onPressed: () => value.i = value.i + 1, ) ], ); }, ), ), ), ), ); } } class NumberTile extends StatelessWidget { final int number; const NumberTile({required this.number, super.key}); @override Widget build(BuildContext context) { return ListTile( title: Text('$number'), ); } } class ChangeNumber extends ChangeNotifier { int _i = 0; int get i => _i; set i(int value) { _i = value; notifyListeners(); } }
额外说明
如果你的ReorderableListView后续会有多个子项,确保每个子项的Key都是唯一且稳定的(比如基于数据的唯一ID,而非动态变化的数值),这样既能保证重新排序功能正常,也不会干扰内部组件的动画逻辑。
内容的提问来源于stack exchange,提问作者Andreas Garvik
相关产品推荐
相关产品推荐

