由于我的代码中有setState(),我的动画效果不佳

时间:2019-08-22 07:58:14

标签: flutter dart setstate flutter-animation

我的动画网页浏览量和列表浏览量相互关联。但是我有一个由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,),
        ],
      ),
    );
  }
}

我在页面更改的2个位置和应用程序的主要列表位置使用setState。这是我的应用程序的样子。

SNAP 1

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

1 个答案:

答案 0 :(得分:1)

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

当只有CircularProgressIndicator()旋转时,调试模式下的动画会出现性能问题。这是由于在调试模式下Dart会获取已编译的JIT而不是AOT的事实。因此,在动画过程中绘制UI时,绘图引擎需要每秒编译60次,才能像在AOT模式下一样平稳地运行。正如人们可能会猜测的那样,这将占用大量资源。

只要您不致电setState({})上的AnimationController..addListener(),就可以实现特定的实现。有关动画和setState({})https://medium.com/flutter-community/flutter-laggy-animations-how-not-to-setstate-f2dd9873b8fc的更多详细信息,请参考本文。