我正在尝试在Flutter中创建类似于WhatsApp仪表板的UX。我创建了一个带有AppBar的脚手架,并将TabBar放在bottomNavigationBar插槽而不是AppBar的底部插槽中。每个TabBarView子级都是一个StreamBuilder,用于侦听特定的流。问题在于,每当流发出一个值时,StreamBuilder都会重新生成(通过日志记录生成函数进行检查),但是直到我切换选项卡并返回到该选项卡时,UI才会更新。
我尝试创建一个托管StreamBuilder的有状态小部件,并将其实例化为TabBarView的子级。我还尝试将侦听器添加到流中并在那里调用setState,但是它也不起作用。
我希望每当收到聊天消息时页面都会更新UI,但是直到我切换标签页后页面才会更新。
body: TabBarView(
controller: _tabController,
children: <Widget>[
ChatListView(),
...
class ChatListView extends StatefulWidget {
@override
_ChatListViewState createState() => _ChatListViewState();
}
class _ChatListViewState extends State<ChatListView>
with AutomaticKeepAliveClientMixin {
List<ListTile> itemList = <ListTile>[];
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: chatsListBloc.chatList,
builder: (context, snapshot) {
print("rebuilt");
if (!snapshot.hasData) {
chatsListBloc.fetchChatList();
return Center(
child: CircularProgressIndicator(),
);
} else {
if (snapshot.data.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'You have not started any chat yet. To start a chat, click on the Start Chat icon.',
textAlign: TextAlign.center,
),
),
);
} else {
List<ChatListItem> dataList = List<ChatListItem>.from(snapshot.data);
itemList.clear();
for (int i = 0; i < dataList.length; i++) {
itemList.add(ListTile(
onTap: () {
}
},
title: Text(dataList[i].displayName),
subtitle: dataList[i].lastMessage,
leading: CircleAvatar(
backgroundColor: Colors.blueGrey,
backgroundImage:MemoryImage(dataList[i].avatar),
child: Stack(
children: <Widget>[
Icon(
Icons.account_circle,
size: 40,
),
(dataList[i].type == ChatType.Incognito)
? Icon(Icons.lock,
color: Colors.blueGrey[700], size: 10)
: Container(),
],
),
),
trailing: StreamBuilder(
stream: Stream.periodic(Duration(seconds: 1),
(computationCount) => computationCount)
.asBroadcastStream(),
builder: (context, snapshot) => Text(timeLabel(
DateTime.fromMillisecondsSinceEpoch(
dataList[i].lastAccessed))),
)));
}
return ListView(
children: itemList,
);
}
}
});
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => false;
}