Printer
Printer

Reputation: 465

Flutter Drawer gets rebuilt everytime i open it

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

Answers (1)

rickimaru
rickimaru

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

Related Questions