You can try something like this. Widget inside drawer: will always be rebuilt because it is disposed when it is closed. You can just perform a simple checking what widget to return based from its state.
In this example, if state is still null it will fetch the data using FutureBuilder. When it is already fetched, it will directly return the Drawer widget.
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
String grade; // Sample state
return Scaffold(
appBar: AppBar(title: const Text('Home')),
drawer: Builder(
builder: (_) {
if (grade != null) {
return MyDrawer(grade);
}
return FutureBuilder<String>(
future: Future<String>.delayed(
const Duration(seconds: 5),
() => grade = 'A+',
),
builder: (_, AsyncSnapshot<String> snapshot) {
print('>>>>>>> snapshot = ${snapshot.data}');
return MyDrawer(snapshot.data);
},
);
},
),
);
}
}
class MyDrawer extends StatelessWidget {
const MyDrawer(this.grade);
final String grade;
@override
Widget build(BuildContext context) {
print('>>>>>>>>>>>>>>>>>>>> Build');
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
const UserAccountsDrawerHeader(
accountName: Text('Lisa Simpsons'),
accountEmail: Text('lisa.simpsons@thesimpsons.com'),
),
Text('Grade A - Student${grade == null ? "" : " >>>>>> ($grade)"}')
],
),
);
}
}
Update: Sample using provider.
class SampleState extends ChangeNotifier {
SampleState() {
fetchGrade();
}
String _grade;
String get grade => _grade;
Future<void> fetchGrade() async {
print('>>>>>>>>>>>>>>>>>>>> FETCHING GRADE');
await Future<String>.delayed(const Duration(seconds: 5));
_grade = 'A+';
notifyListeners();
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<SampleState>(
create: (_) => SampleState(),
builder: (_, __) => Scaffold(
appBar: AppBar(title: const Text('Home')),
drawer: MyDrawer(),
),
);
}
}
class MyDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('>>>>>>>>>>>>>>>>>>>> Build');
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
const UserAccountsDrawerHeader(
accountName: Text('Lisa Simpsons'),
accountEmail: Text('lisa.simpsons@thesimpsons.com'),
),
Consumer<SampleState>(
builder: (_, SampleState state, __) {
print('>>>>>>>>>>>>>>>>>>>> REBUILD');
final String append =
state.grade == null ? '' : ' >>>>>>>>>> (${state.grade})';
return Text('Grade A - Student$append');
},
),
],
),
);
}
}