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

标签 flutter dart setstate flutter-animation

我有相互关联的动画页面 View 和 ListView 。但是我有一个由 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 和我的应用程序的前导 listtile 上的 2 个地方使用了 setState。这是我的应用程序的样子。

SNAP 1

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

最佳答案

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

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

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

关于flutter - 由于代码中的 setState(),我有滞后动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57604622/

相关文章:

javascript - this.setState 使变量未定义?

reactjs - React setState/getState 和异步

android - Flutter:TextButton 中的 setState 不起作用

flutter - flutter 中没有名称为 'nullOk' 的命名参数错误

android - 一旦应用程序进入后台,在一定持续时间后 flutter 运行代码?

unit-testing - 为什么 `#import(" Dart :unittest")` can' t run?

flutter - 不可变或可变数据模型,应该用于设计Google表单,Google Doc等软件吗?

android - 键盘向上滑动并覆盖 Flutter 中的 TextField

flutter - 如何在 flutter 中获得渐变底部导航选项卡?

flutter - 如何从ListView获取值列表