Reputation: 681
I have a image in my Drawer sidemenu where the path to it is stored in a final object named userdata
:
class MyDrawer extends StatelessWidget {
MyDrawer({Key key, this.userdata}) : super(key: key);
final User userdata;
@override
Widget build(BuildContext context) {
return new Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
if (userdata != null) ...[
DrawerHeader(
decoration: BoxDecoration(color: Colors.green),
child: Stack(children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: ClipOval(
child: userdata.image == '' || userdata.image == null
? CircleAvatar(
radius: 50,
backgroundColor: Colors.white,
backgroundImage: AssetImage('assets/images/avatar.png'))
: Image.network(
userdata.image,
width: 100,
height: 100,
fit: BoxFit.cover,
),
)),
When I am now on a page (profile.dart
) where I can update my profile image (which is pushed by the drawer -sidemenu
-)
How can I update the userdata
object in the drawer class?
I found some ideas like streams, but is this really neccessary ?
edit: profile.dart
class ProfilePage extends StatefulWidget {
@override
_MyProfilePageState createState() => _MyProfilePageState();
}
class _MyProfilePageState extends State<ProfilePage> {
final _formKey = GlobalKey<FormState>();
final _username = TextEditingController();
final _email = TextEditingController();
final _firstname = TextEditingController();
final _lastname = TextEditingController();
final picker = ImagePicker();
String image = '';
@override
void initState() {
ProfileApi().getProfile().then((user) {
setState(() {
this._username.text = user.sId;
this._email.text = user.email;
this._firstname.text = user.firstname;
this._lastname.text = user.lastname;
this.image = user.image;
});
});
super.initState();
}
.....
changeUser() async {
try {
User userdata = await ProfileApi().updateProfile(
this._username.text, this._email.text, this._firstname.text, this._lastname.text);
//call some function here to update userdata in my drawer <--
Fluttertoast.showToast(msg: 'Profile updated');
} on Exception catch (error) {
Fluttertoast.showToast(msg: error.toString());
return;
}
}
i also have a storage class where the userdata object is also provided:
class UserStorage {
Future<User> getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String userdata = prefs.getString('userdata') ?? '';
if (userdata != "") {
dynamic user = json.decode(userdata);
return User.fromJson(user);
} else {
return null;
}
}
}
Upvotes: 0
Views: 217
Reputation: 4763
Keep your userData
content in a global variable
globals.dart
file
library globals;
ValueNotifier userDataNotifier = ValueNotifier(null);
Convert your MyDrawer
class to StatefulWidget
and remove the User
variable inside it. Then use your variable in a ValueListenableBuilder
widget
import 'globals.dart' as globals; // ...
class MyDrawer extends StatefulWidget {
MyDrawer({Key key}) : super(key: key);
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
@override
Widget build(BuildContext context) {
return Drawer(
//...
Align(
//...
child: ValueListenableBuilder(
valueListenable: globals.userDataNotifier,
builder: (context, userdata, _) {
return ClipOval(
child: userdata.image == '' || userdata.image == null
? CircleAvatar(
radius: 50,
backgroundColor: Colors.white,
backgroundImage: AssetImage('assets/images/avatar.png'))
: Image.network(
userdata.image,
width: 100,
height: 100,
fit: BoxFit.cover,
),
);
},
),
),
);
}
}
Finally in your changeUser
function, simply change the content of your notifier
import 'globals.dart' as globals;
// ...
changeUser() async {
try {
User userdata = await ProfileApi().updateProfile(this._username.text, this._email.text, this._firstname.text, this._lastname.text);
// simply change the content of userData
globals.userDataNotifier = userdata;
Fluttertoast.showToast(msg: 'Profile updated');
} on Exception catch (error) {
Fluttertoast.showToast(msg: error.toString());
return;
}
}
Upvotes: 1