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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:22:59