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

Flutter GridView Item点击动画问题:点击单个item所有项同时动画如何修复

问题根因

你当前的代码中整个页面State只持有一个全局共享的动画控制器和动画实例,所有GridView的item都绑定了同一个动画参数,只要触发控制器,所有绑定了该动画的组件都会同步执行动画,所以会出现点击任意item所有项一起动的问题。

解决方案

最优方案是将单个Grid项抽离为独立的Stateful组件,每个组件内部自行管理自己的动画控制器,实现每个item的动画独立互不干扰,修改代码如下:

首先抽离独立的Grid Item组件:

// 独立管理自身动画的Grid Item组件
class PetGridItem extends StatefulWidget {
  final String assetUrl;
  // 如果需要向外传递点击事件可增加onTap回调参数
  const PetGridItem({super.key, required this.assetUrl});

  @override
  State<PetGridItem> createState() => _PetGridItemState();
}

class _PetGridItemState extends State<PetGridItem> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    _animation = Tween<double>(begin: 1.0, end: 1.2).animate(_animationController);
    _animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _animationController.reverse();
      }
    });
  }

  @override
  void dispose() {
    // 销毁控制器避免内存泄漏
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      clipBehavior: Clip.antiAliasWithSaveLayer,
      shape: const CircleBorder(),
      elevation: 5.0,
      shadowColor: CustomColor.mailColor,
      child: InkResponse(
        onTap: (){
          // 仅触发当前item的动画
          _animationController.forward();
        },
        child: ScaleTransition(
          scale: _animation,
          child: Image.asset(
            widget.assetUrl,
            fit: BoxFit.cover,
            height: 70.0,
            width: 70.0,
          ),
        ),
      ),
    );
  }
}

然后修改原页面的代码,移除全局动画相关逻辑,直接调用抽离好的组件:

class ChoosePetState extends State with TickerProviderStateMixin
{
  @override
  void initState()
  {
    super.initState();
  }

  @override
  Widget build(BuildContext context)
  {
    SystemChrome.setSystemUIOverlayStyle(
        const SystemUiOverlayStyle(statusBarColor: CustomColor.mailColor));
    return SafeArea(
      child: Scaffold(
        body: CustomScrollView(
          slivers: <Widget>[
            SliverToBoxAdapter(
              child: SizedBox(
                width: double.infinity,
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(20.0, 20.0,20.0,30.0),
                  child: Text(
                    Strings.choosePet,
                    style: GoogleFonts.firaSans(
                      fontSize: 32.0,
                      fontWeight: FontWeight.bold,
                      color: CustomColor.colorPrimaryDark.withOpacity(0.7),
                    ),
                  ),
                ),
              ),
            ),
            SliverPadding(
              padding: const EdgeInsets.fromLTRB(10.0,0.0,10.0,30.0),
              sliver:  SliverGrid(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                  childAspectRatio: 0.91,
                  mainAxisSpacing: 1.0,
                  crossAxisSpacing: 1.0,
                ),
                delegate: SliverChildBuilderDelegate(
                      (context, index) {
                    return PetGridItem(assetUrl: list[index].url);
                  },
                  childCount: list.length,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:06:04