【发布时间】:2020-01-04 04:26:25
【问题描述】:
我在设计 UI 时使用 Flutter 和动画等内容,但是当我开始使用 Firestore 向 UI 中添加两个带有列表视图的 StreamBuilders 时,替换了虚拟数据,动画从黄油般的平滑变成了非常迟钝的我'宁愿没有它们。
我正在使用两个AnimationControllers 两个控件两种类型的动画,我使用this 教程来学习如何在没有setStates 的情况下进行操作,并且在我添加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 的列表,每个ListView,一个水平,另一个垂直。两者看起来非常相似。
StreamBuilder 小部件:
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,
));
});
}
当我评论其中一个StreamBuilders 时,它只是滞后,但是,第二个 AUPostsList 比 ChatsList 滞后得多。但是当两者都显示时,动画在发布模式下真的真的很滞后,在调试模式下不存在。两者都被注释掉,然后在调试和发布模式下都非常流畅。
是的,在 iOS 和 Android 上都有相同的效果。
【问题讨论】:
-
这是滞后的,因为它在 UI 线程上运行本机 Firestore 代码。我担心一个问题会永远阻碍 Flutter。在发布模式下感觉应该会好一些,但是直到(如果)他们弄清楚如何将工作卸载到非 UI 线程,我不希望我们会看到 Firestore 插件的出色性能。
标签: flutter flutter-animation stream-builder