问题描述
class AttendantMainPage extends StatefulWidget {
final String? email;
AttendantMainPage({
Key? key,this.email,}) : super(key: key);
@override
_AttentdantMainPageState createState() => _AttentdantMainPageState();
}
class _AttentdantMainPageState extends State<AttendantMainPage> {
var user = FirebaseAuth.instance.currentUser;
int _currentIndex = 1;
late final List<Widget> _children;
@override
void initState() {
_children = [
ProfilePage(),AttendantHomePage(),ChatListPage(),];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentIndex],bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.white,selectedItemColor: Color(0xffe96cbd),onTap: onTabpressed,currentIndex: _currentIndex,items: [
BottomNavigationBarItem(
icon: new Icon(
CustomIcons.user,),label: 'Profile'),BottomNavigationBarItem(
icon: new Icon(
CustomIcons.home,label: 'Home'),BottomNavigationBarItem(
icon: new Icon(
Icons.mail,label: 'Messages'),],);
}
void onTabpressed(int index) {
setState(() {
_currentIndex = index;
});
}
}
而且我在所有屏幕上都有 streamBuilder。当我更换屏幕时,我的流构建器会一次又一次地被调用。我猜使用firebase可能真的很贵。这是其中一个屏幕的代码,谁能告诉我如何避免在页面之间切换后不必要的调用?
class ProfilePage extends StatefulWidget {
@override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
bool enabled = false;
late FocusNode myFocusNode;
var user = FirebaseAuth.instance.currentUser;
late Stream<DocumentSnapshot> stream;
@override
void initState() {
stream = FirebaseFirestore.instance
.collection('users')
.doc(user!.uid)
.snapshots();
myFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double _width = MyUtility(context).width;
double _height = MyUtility(context).height;
return Scaffold(
backgroundColor: Color(0xfff0eded),body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),child: Container(
width: _width,height: _height,child: Column(
children: [
Stack(
alignment: AlignmentDirectional.topCenter,children: [
Container(
width: _width,height: _height * 0.4,Container(
height: _height * 0.25,decoration: Boxdecoration(
gradient: LinearGradient(
begin: Alignment.topRight,end: Alignment.bottomLeft,colors: [
Color(0xff4d629f),Color(0xffe96cbd),Positioned(
bottom: _height * 0.02,child: ProfileImage(
width: _width * 0.5,height: _height * 0.25,userEmail: user!.email!,Positioned(
right: _width * 0.25,bottom: _height * 0.05,child: Clipoval(
child: Container(
color: Colors.white,child: Padding(
padding: const EdgeInsets.all(2),child: Clipoval(
child: Material(
color: Color(0xffe96cbd),// button color
child: InkWell(
splashColor: Color(0xffffc2ea),// inkwell color
child: SizedBox(
width: _width * 0.08,height: _height * 0.04,child: Padding(
padding: const EdgeInsets.all(8.0),child: Icon(
Icons.edit,color: Colors.white,size: MyUtility(context).width * 0.04,)),onTap: () {
getimage().then((value) {
uploadFile(value);
});
},Stack(
alignment: AlignmentDirectional.topCenter,children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: 10,horizontal: _width * 0.05,child: OverlayPanel(
width: _width * 0.9,child: Padding(
padding: EdgeInsets.all(
_height * 0.04,child: Column(
children: [
StreamBuilder<DocumentSnapshot>(
stream: stream,builder: (context,snapshot) {
if (snapshot.hasData) {
return TextFormField(
focusNode: myFocusNode,enabled: enabled,initialValue: snapshot.data!['username'],textAlign: TextAlign.center,style: TextStyle(
fontSize: 30,color: Color(0xff273150),onFieldSubmitted: (input) {
setState(() {
enabled = false;
});
print(input);
FirebaseFirestore.instance
.collection('users')
.doc(user!.uid)
.update({'username': input});
},);
} else
return TextField(
enabled: false,style: TextStyle(fontSize: 30),);
}),SizedBox(
height: _height * 0.02,Text(user!.email!,style: TextStyle(
fontSize: 18.0,Text(
//Todo great idea to use currentUser: user!.displayName as a user Type to check it all easier and faster
'Type: ${'Attendant'}',style: TextStyle(
fontSize: 14.0,Positioned(
right: _width * 0.1,top: _height * 0.025,height: _width * 0.08,size: _width * 0.04,onTap: () async {
setState(() {
enabled = !enabled;
});
await Future.delayed(
Duration(milliseconds: 10),() => {
FocusScope.of(context)
.requestFocus(myFocusNode),});
},Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),child: Container(
width: _width,decoration: Boxdecoration(
color: Color(0xfff0eded),child: Container(
child: Column(
children: [
CustomButton(
width: _width * 0.9,icon: Icons.lock,text: 'Change Password',onpressed: () {
//Todo add possibility to change password
},CustomButton(
width: _width * 0.9,icon: Icons.delete,text: 'Delete Account',onpressed: () {},icon: Icons.logout,text: 'Log Out',onpressed: () async {
await FirebaseAuth.instance.signOut();
Navigator.pop(context);
},);
}
}
解决方法
更改我的 AttendantMainPage
中的正文:
body: _children[_currentIndex],
到
body: IndexedStack(
index: _currentIndex,children: _children,),
解决了问题。
感谢大家的帮助!