skip to Main Content

I have a flutter app with drawer navigation. When open, the drawer is overlapping a widget (let’s call it Screen_1).

I would like to force the Screen_1 rebuild when the user dismisses the drawer. What is the best way to do it? Thanks.

EDIT. A specific example: In the drawer the user can change their picture. But when they dismiss the drawer (eg by clicking outside of it), Screen_1 still shows their old picture. I’d like Screen_1 to show the new picture.

2

Answers


  1. I have a few suggestions that might help you and you can choose based on your need and u can look into these:

    ValueNotifier : https://api.flutter.dev/flutter/foundation/ValueNotifier-class.html

    If you are pressing a button to close it you can use:
    Navigator.pushReplacement

    Or lastly
    callback function

    example:

        import 'package:flutter/material.dart';
        
        void main() {
          runApp(MyApp());
        }
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: HomeScreen(),
            );
          }
        }
        
        class HomeScreen extends StatelessWidget {
          void _rebuildScreen1(BuildContext context) {
            Navigator.pop(context); // Close the drawer
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(
                builder: (context) => Screen_1(rebuildCallback: _rebuildScreen1),
              ),
            );
          }
        
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                title: Text('Drawer Example'),
              ),
              drawer: Drawer(
                child: ListTile(
                  title: Text('Close Drawer'),
                  onTap: () => _rebuildScreen1(context), // Call the rebuild callback
                ),
              ),
              body: Screen_1(rebuildCallback: _rebuildScreen1),
            );
          }
        }
        
        class Screen_1 extends StatefulWidget {
          final VoidCallback rebuildCallback;
        
          Screen_1({required this.rebuildCallback});
        
          @override
          _Screen_1State createState() => _Screen_1State();
        }
        
        class _Screen_1State extends State<Screen_1> {
          @override
          Widget build(BuildContext context) {
            return Center(
              child: TextButton(
                onPressed: () => widget.rebuildCallback(), // Use the rebuild callback
                child: Text('Rebuild Screen 1'),
              ),
            );
          }
        }
    
    
    Login or Signup to reply.
  2. First this is my user/authentication class and i user change ChangeNotifier so i can notify widget when needed to rebuild with the new data also i use setProfilePicture() to update the data and call notifyListeners():

        class UserAuthentication with ChangeNotifier {// added with ChangeNotifier
          final FirebaseAuth _auth = FirebaseAuth.instance;
          final FirebaseFirestore _firestore = FirebaseFirestore.instance;
          final FirebaseStorage _storage = FirebaseStorage.instance;
        
          String? _verificationId;
          static Student? _student;
        
          User? get user => _auth.currentUser;
          bool get isLoggedIn => _auth.currentUser != null;
            Future<void> setProfilePicture(File img) async {
            final String fileName =
                'profilePics/${user!.uid}.png'; // Using user ID as the file name
        
            // Attempt to delete the existing profile picture, if there is one
            FirebaseStorage.instance.ref(fileName).delete().catchError((error) {
              // You can ignore the error if you don't want to do anything when the file doesn't exist
            });
        
            // Upload the new profile picture
            final UploadTask task = FirebaseStorage.instance.ref(fileName).putFile(img);
        
            // Once the upload completes, get the download URL
            final TaskSnapshot snapshot = await task;
            final String downloadUrl = await snapshot.ref.getDownloadURL();
        
            // Update the photo URL for the user
            await user!.updatePhotoURL(downloadUrl); //updating user object
            notifyListeners(); //added this to notify listeners
          }
        }
    

    so if i want a widget to be rebuild i will do this by using Consumer:

    
        Consumer<UserAuthentication>( // consumer will listen for changes and rebuilds when needed
                          builder: (context, value, _) {
                            return SizedBox(
                              width: 100.w, 
                              child: CircleAvatar(
                                radius: 50.r, 
                                backgroundImage: NetworkImage(
                                  value.user == null
                                      ? 'https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?r=pg'
                                      : value.user!.photoURL ??
                                          'https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?r=pg', // Replace with your image URL
                                ),
                              ),
                            );
                          },
                        ),
    
    

    dont forget that you need to add the provider in main like this:

        MultiProvider(
              providers: [
                ChangeNotifierProvider(create: (_) => UserAuthentication()),    
              ],
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search