颤动的动画变得非常缓慢

时间:2019-08-31 02:47:44

标签: flutter flutter-animation stream-builder

我当时在设计UI时比较混乱,并带有动画和其他内容,但是当我开始使用Firestore向列表中添加两个具有列表视图的StreamBuilders到UI替换虚拟数据时,动画从黄油般平滑过渡到令人la目结舌我宁愿不在那儿。

我正在使用两个AnimationControllers和两个控制两种类型的动画,我使用了this教程来学习如何在没有setStates的情况下进行操作,并且在我添加{{ 1}}。

一个StreamBuilders为淡入淡出过渡设置动画效果,另一个为垂直平移以将列表小部件隐藏在屏幕之外。

代码:

AnimationController

AnimationController _fadeAnimationController; AnimationController _margAnimationController; @override void initState() { super.initState(); this._fadeAnimationController = AnimationController( value: 1.0, duration: Duration(milliseconds: 300), reverseDuration: Duration(milliseconds: 300), vsync: this, ); this._margAnimationController = AnimationController( value: 0.0, upperBound: widget.deviceHeight, duration: Duration(milliseconds: 300), reverseDuration: Duration(milliseconds: 300), vsync: this, ); } @override void dispose() { super.dispose(); this._fadeAnimationController.dispose(); this._margAnimationController.dispose(); } @override Widget build(BuildContext context) { return Material( color: Colors.black, child: Stack( children: <Widget>[ FadeTransition( // FIRST ANIMATED WIDGET opacity: this._fadeAnimationController, child: Container(color: Config.pColor), ), // Other unrelated widgets… Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ Platform.isIOS ? CupertinoNavigationBar( automaticallyImplyLeading: false, backgroundColor: Colors.transparent, border: Border.all(color: Colors.transparent, width: 0.0, style: BorderStyle.none), middle: Text('Dost', style: TextStyle(color: Config.bgColor)), trailing: this._cameraIconButton(), transitionBetweenRoutes: false, heroTag: 'CameraAppBar') : AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.transparent, elevation: 0.0, title: Text('Dost', style: TextStyle(color: Config.bgColor)), actions: <Widget>[this._cameraIconButton()], ) ]), Expanded( child: AnimatedBuilder( // SECOND ANIMATED WIDGET animation: this._margAnimationController, builder: (_, child) => Transform.translate( offset: Offset(0, this._margAnimationController.value), child: child, ), child: HomePage( // STREAMBUILDERS ARE INSIDE THIS WIDGET cUser: InheritedUser.of(context).user, showCamera: () { this._openCloseCamera(); }, showPosts: () { Funcs.popup(context: context, w: CUPostsPage(cUser: InheritedUser.of(context).user)); }, showSettings: () { Funcs.navigateTo(context: context, w: SettingsPage(), fullscreenDialog: false); }), ), ) ], ) ], ), ); } 小部件基本上具有两个HomePage()的列表,每个列表都有一个StreamBuilders,一个为水平,另一个为垂直。两者看起来非常相似。

StreamBuilder小部件:

ListView

AND

class ChatsList extends StatelessWidget {
  @override
  Widget build(BuildContext context) => StreamBuilder<List<Chat>>(
      initialData: InheritedUser.of(context).user.chats,
      stream: APIs().chats.chatsStream(cUserID: InheritedUser.of(context).user.userID),
      builder: (context, snap) {
        User cUser = InheritedUser.of(context).user;

        cUser.chats.clear();
        cUser.chats = snap.data;

        return ListView.builder(
            physics: BouncingScrollPhysics(),
            shrinkWrap: true,
            padding: EdgeInsets.only(top: 0.0),
            itemBuilder: (context, index) => ChatItem(chat: cUser.chats[index]),
            itemCount: cUser.chats.length);
      });
}

当我在其中一个class AUPostsList extends StatelessWidget { final ScrollController scrollController; AUPostsList({this.scrollController}); @override Widget build(BuildContext context) => StreamBuilder<List<Post>>( initialData: [], stream: APIs().posts.auPostsStream(cUserID: InheritedUser.of(context).user.userID), builder: (context, snap) { Map<String, List<Post>> _posts = {}; List<String> _postsUserIDs = []; snap.data.forEach((post) { if (_posts[post.user.documentID] == null) { _posts[post.user.documentID] = [post]; } else { _posts[post.user.documentID].add(post); } if (!_postsUserIDs.contains(post.user.documentID)) { _postsUserIDs.add(post.user.documentID); _posts[post.user.documentID].sort((a, b) => b.createdAt.compareTo(a.createdAt)); } }); return Container( height: ((MediaQuery.of(context).size.width - 80.0) / 3) * 1.5, child: ListView.separated( scrollDirection: Axis.horizontal, controller: this.scrollController, physics: AlwaysScrollableScrollPhysics(), shrinkWrap: true, padding: EdgeInsets.only(top: 0.0, left: 10.0, right: 10.0), itemBuilder: (context, index) => AUPostItem(posts: _posts[_postsUserIDs[index]]), separatorBuilder: (context, index) => Container(), itemCount: _postsUserIDs.length, )); }); } 上发表评论时,它只是很慢,但是第二个AUPostsList比ChatsList慢得多。但是当两者都显示时,动画在发布模式下真的很滞后,在调试模式下却不存在。两者都被注释掉了,那么在调试和发布模式下都非常顺畅。

是的,在iOS和Android上都具有相同的效果。

1 个答案:

答案 0 :(得分:1)

您可以使用侦听器来侦听Firestore数据库的更新,而不必使用流构建器,而在有更新时侦听setState。由于某种原因,它对我来说效果更好。在您的情况下,将是这样的:

List<DocumentSnapshot> posts;
var query = Firestore.instance
    .collection('posts')
    .where('userId', isEqualTo: userId);

listener() async {
  query.snapshots().listen((querySnapshot) {
    querySnapshot.documentChanges.forEach((changes) {
      if (posts.every((f) => f != changes.document)) {
        setState(() {
          posts.add(changes.document);
        });
      } else {
        setState(() {
          posts[posts.indexWhere((f) =>
                  f.data['postId'] == changes.document.data['postId'])] =
              changes.document;
        });
      }
    });
  });
}

当然,您必须根据需要调整所有数据。