#android #flutter
#Android #флаттер
Вопрос:
Я внедряю виджет выхода из системы, который будет отображаться только при входе пользователя в систему. Я использовал этот DrawerLogout
виджет внутри Drawer
с ListView
class DrawerLogout extends StatefulWidget {
@override
_DrawerLogoutState createState() => _DrawerLogoutState();
}
class _DrawerLogoutState extends State<DrawerLogout> {
Stream authState = FirebaseAuth.instance.authStateChanges();
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: authState,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListTile(
title: Text(
'Logout',
style: TextStyle(color: Theme.of(context).errorColor),
),
onTap: () {
FirebaseAuth.instance.signOut();
},
);
}
return Container();
});
}
}
Что-то вроде этого:
Scaffold(
drawer: Drawer(
child: ListView(
children:[
...
...
DrawerLogout(),
])
)
)
Проблема в том, что кнопка выхода отображается только в первый раз, когда я открываю ящик, после закрытия ящика и повторного открытия кнопка выхода исчезает.
Это код ошибки, когда он исчезает:
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: Cannot add new events while doing an addStream
Комментарии:
1. Инициализирует ли это
Stream authState = FirebaseAuth.instance.authStateChanges();
вinitState()
справке?2. @JoyTerence это работает! Большое вам спасибо! Не могли бы вы использовать ответ, чтобы я мог его принять?
Ответ №1:
Как обсуждалось в комментариях, перемещение инициализации состояния initState
решило проблему.
Проблема была вызвана добавлением новых событий в удаленный поток. Согласно документам:
Если метод построения состояния зависит от объекта, который сам может изменять состояние, например, ChangeNotifier или Stream, или какого-либо другого объекта, на который можно подписаться для получения уведомлений, то обязательно правильно подписывайтесь и отменяйте подписку в initState , didUpdateWidget и dispose:
- В initState подпишитесь на объект.
- В didUpdateWidget отпишитесь от старого объекта и подпишитесь на новый, если обновленная конфигурация виджета требует замены объекта.
- В dispose отпишитесь от объекта.
Ответ №2:
Как и предполагал @JoyTerence, инициализация потока в initState работает!
class DrawerLogout extends StatefulWidget {
@override
_DrawerLogoutState createState() => _DrawerLogoutState();
}
class _DrawerLogoutState extends State<DrawerLogout> {
Stream authState;
@override
void initState() {
// TODO: implement initState
super.initState();
authState = FirebaseAuth.instance.authStateChanges();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: authState,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListTile(
title: Text(
'Logout',
style: TextStyle(color: Theme.of(context).errorColor),
),
onTap: () {
FirebaseAuth.instance.signOut();
},
);
}
return Container();
});
}
}