我是 Flutter 的新手,我正在尝试构建一个简单的应用程序。每当我从 EditProfileScreen 更新配置文件详细信息并尝试通过 LandingScreen 返回到 ProfileScreen 时,FutureBuilder 会继续触发并出现 LogoScreen。如何避免这种情况?
我尝试使用 Navigator pop,但在这种情况下我的新数据没有更新。我不能直接导航到 ProfileScreen,因为我不想松开底部导航栏。任何人都可以建议我这样做的正确方法吗?
着陆屏():
class LandingScreen extends StatefulWidget {
final int index;
LandingScreen({this.index});
@override
_LandingScreenState createState() => _LandingScreenState();
}
class _LandingScreenState extends State<LandingScreen> {
int _currentIndex = 0;
List<Futsal> list;
List<Search> listHistory;
List<Futsal> futsalList;
Future<dynamic> loadDataFuture;
final List<Widget> _children = [
HomePage(),
ExploreScreen(),
ProfileDetails(),
];
@override
void initState() {
onTappedBar(widget.index);
loadDataFuture = getFutureData();
super.initState();
}
void onTappedBar(int index) {
setState(() {
_currentIndex = index;
});
}
Future getFutureData() async {
listHistory = await fetchSearchs();
futsalList = await fetchFutsals();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: new FutureBuilder(
future: loadDataFuture,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Please close the application and Try Again.');
case ConnectionState.waiting:
return LogoScreen();
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
automaticallyImplyLeading: false,
backgroundColor: kPrimaryLightColor,
title: Text(
'letsfutsal',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
color: kPrimaryColor,
onPressed: () {
showSearch(
context: context,
delegate: SearchScreen(
futsalList: futsalList,
listHistory: listHistory));
},
),
],
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTappedBar,
currentIndex: _currentIndex,
selectedItemColor: kPrimaryColor,
unselectedItemColor: Colors.black38,
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: new FaIcon(FontAwesomeIcons.home),
title: new Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.safari),
title: Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.solidUserCircle),
title: Text(''),
),
],
),
);
}
},
),
);
}
}
配置文件屏幕():
class ProfileDetails extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CustomUserProvider()),
ChangeNotifierProvider(create: (context) => MyBookingsProvider()),
],
child: SafeArea(
child: Scaffold(
backgroundColor: kPrimaryLightColor,
appBar: new AppBar(
automaticallyImplyLeading: false,
elevation: 0,
title: Text(
'Profile',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: [
FlatButton.icon(
onPressed: () {},
icon: Icon(
FontAwesomeIcons.signOutAlt,
color: kPrimaryColor,
),
label: Text(
'Log Out',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
),
body: new Container(
padding: const EdgeInsets.all(15.0),
child: new Center(
child: new Column(
children: <Widget>[
UserDetails(),
MyBookingsList(),
],
),
),
),
),
),
);
}
}
class UserDetails extends StatelessWidget {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final userProvider = Provider.of<CustomUserProvider>(context);
if (userProvider.user.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
new CircularImageContainer(
radius: 50,
imageUrl: "assets/images/profile.png",
),
SizedBox(height: size.height * 0.03),
Text(
userProvider.user[0].name != null ? userProvider.user[0].name : "",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
SizedBox(height: size.height * 0.01),
Text(
userProvider.user[0].address != null
? userProvider.user[0].address
: "",
),
FlatButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return EditProfileScreen(
user: userProvider.user[0],
);
},
),
);
},
icon: Icon(
Icons.edit,
color: kPrimaryColor,
),
label: Text(
'Edit Profile',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
);
}
}
}
class MyBookingsList extends StatelessWidget {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final bookingsProvider = Provider.of<MyBookingsProvider>(context);
if (bookingsProvider.bookings.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
ScrollListContainer(
text: "My Bookings",
size: size,
),
ListView.builder(
shrinkWrap: true,
itemCount: bookingsProvider.bookings.length,
scrollDirection: Axis.vertical,
physics: BouncingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Card(
child: Container(
width: 150,
child: ExpansionTile(
title: Text(
index.toString() +
'. ' +
bookingsProvider
.bookings[index].futsal.customUser.name !=
null
? bookingsProvider
.bookings[index].futsal.customUser.name
: "",
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
children: <Widget>[
ListTile(
title: Text(
bookingsProvider.bookings[index].status,
),
subtitle: Text(
'For ' + bookingsProvider.bookings[index].bookedFor,
),
dense: true,
),
],
),
),
);
},
),
],
);
}
}
}
编辑配置文件屏幕():
class EditProfileScreen extends StatefulWidget {
final CustomUser user;
EditProfileScreen({this.user});
@override
_EditProfileScreenState createState() => new _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();
String _name;
String _address;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
void _submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
performUpdate();
}
}
void performUpdate() async {
Map data = {
'name': _name,
'address': _address,
};
var url =MY_URL;
var response = await http.post(url,
headers: {"Accept": "application/json"}, body: data);
print(response.body);
if (response.statusCode == 200) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LandingScreen(index: 2,)));
}
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return new SafeArea(
child: Scaffold(
key: scaffoldKey,
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
// automaticallyImplyLeading: false,
leading: BackButton(
color: kPrimaryColor,
),
elevation: 0,
backgroundColor: kPrimaryLightColor,
title: Text(
widget.user.name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
),
body: new Container(
height: size.height,
width: double.infinity,
padding: const EdgeInsets.all(30.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Edit Details",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.03),
new Form(
key: formKey,
child: new Column(
children: <Widget>[
new TextFieldContainer(
child: new TextFormField(
controller:
TextEditingController(text: widget.user.name),
decoration: new InputDecoration(
labelText: "Name",
icon: Icon(
Icons.person,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter name' : null,
onSaved: (val) => _name = val,
),
),
new TextFieldContainer(
child: new TextFormField(
controller: TextEditingController(
text: widget.user.address != null
? widget.user.address
: ''),
decoration: new InputDecoration(
labelText: "Address",
icon: Icon(
Icons.email,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter your address' : null,
onSaved: (val) => _address = val,
),
),
RoundedButton(
text: "Update",
press: _submit,
),
],
),
),
],
),
),
),
),
);
}
}