我正在设计 UI 和动画和其他东西,但是当我开始添加两个StreamBuilders
列表视图,使用 Firestore,到 UI 替换虚拟数据时,动画从黄油般的平滑变成了太迟钝我宁愿没有他们在那里.
我正在使用两个AnimationControllers
两个控制两种类型的动画,我使用本教程来学习如何在没有它的情况下进行操作,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 上都有相同的效果。