由于代码中的 setState(),我有滞后动画

I have laggy animation because of setState() in my code

我有相互关联的动画综合浏览量和列表浏览量。但是我有一个由 setState 引起的动画问题(我已经测试过删除 setState 并且动画效果很好)。

import 'package:flutter/material.dart';

 const double _listheight = 80;

class LoyaltyPage extends StatefulWidget {
  @override
  _LoyaltyPageState createState() => new _LoyaltyPageState();
}

class _LoyaltyPageState extends State<LoyaltyPage> {
  PageController controller;
  ScrollController listcontroller;
  int selected = 0;
  List<String> images=[
    'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
    'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
    'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
    'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
  ];
  @override
  initState() {
    super.initState();
    controller = new PageController(
      initialPage: selected,
      keepPage: false,
      viewportFraction: 0.7,
    );
    listcontroller = new ScrollController();
  }

  @override
  dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        iconTheme: IconThemeData(color: Colors.black),
        title: Text(
          'Loyalty',
          style: TextStyle(color: Colors.black),
        ),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            flex: 3,
            child: new Container(
              child: new PageView.builder(
                  onPageChanged: (value) {
                  //ADDING THIS SET STATE CAUSE SELECTED COLOR WORKS BUT LAGGY ANIMATION
                  setState(() {
                    selected=value;
                  });
                    listcontroller.animateTo(value*_listheight,duration: Duration(milliseconds: 500),curve: Curves.ease);
                  },
                  itemCount: images.length,
                  controller: controller,
                  itemBuilder: (context, index) => builder(index)),
            ),
          ),
          Expanded(
            flex: 6,
            child: new Container(
              child: new ListView.builder(
                controller: listcontroller,
                itemCount: images.length,
                itemBuilder: (context,index) => _listbuilder(index),
              ),
            ),
          ),
        ],
      ),
    );
  }

  builder(int index) {
    return new AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        double value = 1.0;
        if (controller.position.haveDimensions) {
          value = controller.page - index;
          value = (1 - (value.abs() * .4)).clamp(0.0, 1.0);
        }
        return new Center(
          child: new SizedBox(
            height: Curves.easeOut.transform(value) * 180,
            width: Curves.easeOut.transform(value) * 270,
            child: child,
          ),
        );
      },
      child: new Card(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))),
          semanticContainer: true,
          clipBehavior: Clip.antiAliasWithSaveLayer,
        child:Container(
          child: Image.network(images[index],fit: BoxFit.fill,)
        ),
      ),
    );
  }

  _listbuilder(int index){
    return Container(
      height: _listheight,
      child: Column(
        children: <Widget>[
          ListTileTheme(
            selectedColor: Colors.blueAccent,
            child: ListTile(
              title: Text(images[index],maxLines: 1,overflow: TextOverflow.ellipsis,),
              subtitle: Text('Level : Gold'),
              leading: GestureDetector(
                onTap: (){
                  //ADDING THIS SET STATE CAUSE SELECTED COLOR WORKS BUT LAGGY ANIMATION
                  setState(() {
                    selected=index;
                  });
                  controller.animateToPage(index,duration: Duration(milliseconds: 500),curve: Curves.ease); 
                },
                child: Icon(
                  Icons.credit_card),
              ),
              trailing: Icon(Icons.navigate_next),
              selected: index==selected,//THIS IS THE SELECTED THAT I TRIED TO CHANGE
            ),
          ),
          Divider(height: 1,color: Colors.black45,),
        ],
      ),
    );
  }
}

我在 pagechanged 和我的 app.And 的前导 listtile 的两个地方使用了 setState,这是我的应用程序的样子。

第一个是我的应用程序的预期输出,但它很慢, 第二个有流畅的动画,但文字颜色没有改变。

尝试 运行在发布或配置文件模式下安装您的应用程序。

当只有 CircularProgressIndicator() 正在旋转时,调试模式下的动画存在性能问题。这是因为在调试模式下,Dart 得到编译的 JIT 而不是 AOT。因此,绘图引擎需要编译 60 次/秒,同时将动画期间的 UI 绘制为 运行 与 AOT 模式一样平滑。正如人们所猜测的那样,这将占用大量资源。

只要您不在 AnimationController..addListener() 上调用 setState({}),您的具体实施应该没问题。有关动画和 setState({}): https://medium.com/flutter-community/flutter-laggy-animations-how-not-to-setstate-f2dd9873b8fc 的更多详细信息,请参阅本文。