Reputation: 465
I have been workign on this hours trying to solve why the drawer getting rebuilt everytime i open it. Without any progress, i came here to seek for guidance how can i load it once and rebuild it when i need to?
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home")),
drawer: const MyDrawer(),
);
}
}
class MyDrawer extends StatelessWidget {
const MyDrawer();
@override
Widget build(BuildContext context) {
print("Build");
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text("Lisa Simpsons"),
accountEmail: Text("[email protected]"),
),
Text("Grade A - Student")
],
),
);
}
}
Upvotes: 2
Views: 1432
Reputation: 2490
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('[email protected]'),
),
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('[email protected]'),
),
Consumer<SampleState>(
builder: (_, SampleState state, __) {
print('>>>>>>>>>>>>>>>>>>>> REBUILD');
final String append =
state.grade == null ? '' : ' >>>>>>>>>> (${state.grade})';
return Text('Grade A - Student$append');
},
),
],
),
);
}
}
Upvotes: 2