Introduction to Provider

  1. Getting started
  2. Provider : Wraps around inherited widgets. This package allows you to provide data and state information to descendant widgets.

    flutter provider

    This approach is better. It allows descendant widgets in the subtree to access state information.

    Instead of callbacks, you just wrap Consumers around your widgets. Every time a state changes, those Consumers rebuild the subtree below it.

  3. Provider Overview
  4. Provider is a convenient way to pass state down the widget tree and rebuild your UI when changes occur. You’ll add it to your project next.

    Before you do that, however, you need to understand four concepts:

    1. ChangeNotifier is extended by a class to provide change notifications to its listeners

    2. ChangeNotifierProvider listens for changes to a ChangeNotifier. Widgets below it can access the state object and listen to state changes.

    3. Consumer wraps around part of a widget tree. It rebuilds part of a subtree when the state it listens to changes.

    4. Provider.of allows descendant widgets to access the state object. If you only need access to the state object and don’t need to listen for changes, use this!

    Adding Provider : Provider Installing

  5. Example : My Notes App


    1. Creating Note Model
    2. In the models directory, create a new file called note.dart and add the following code:

      class Note {

        String title;

        String description;

        Note(this.title, this.description);

      }




    3. Crearting NoteManager
    4. In the providers directory, create a new file called notes_manager.dart and add the following code:

      import '../models/note.dart';

      import 'package:flutter/foundation.dart';

       

      class NotesManager extends ChangeNotifier {

        //This manager holds a private array of _noteItems.

        // Only the manager can change and update note items.

        final List<Note> _noteItems = [];

       

        //Provides a public getter method for _noteItems, which is unmodifiable.

        //External entities can only read the list of note items

        List<Note> get noteItems => List.unmodifiable(_noteItems);

       

        //Get the note at index in the list

        Note geNoteByIndex(int index) {

          return _noteItems[index];

        }

       

        //addNote() adds a new note item at the end of the list.

        void addNote(Note note) {

          _noteItems.add(note);

          notifyListeners();

        }

       

        //deleteNoe() deletes a note at a particular index.

        void deleteNote(int index) {

          _noteItems.removeAt(index);

          notifyListeners();

        }

      }



      It’s time to provide this to other widgets.



    5. Providing NoteManager
    6. Open main.dart and add the following imports.

      Then, assign MultiProvider to the runApp. This accepts a list of providers for the entire app.

      ChangeNotifierProvider creates an instance of NoteManager, which listens to _noteItems and notifies its listeners.

      import 'package:flutter/material.dart';

      import 'package:my_notes/screens/new_note_screen.dart';

      import 'package:my_notes/screens/note_screen.dart';

      import 'package:my_notes/screens/notes_screen.dart';

      import 'package:provider/provider.dart';

      import 'providers/notes_manager.dart';

       

      void main() {

        runApp(

          MultiProvider(

            providers: [

              ChangeNotifierProvider(create: (_) => NotesManager()),

            ],

            child: MyApp(),

        ));

      }

       

      class MyApp extends StatelessWidget {

        const MyApp({Key? key}) : super(key: key);

       

        @override

        Widget build(BuildContext context) {

          return MaterialApp(

              title: 'My Notes',

              theme: ThemeData(

                primarySwatch: Colors.blue,

              ),

              routes: {

                "/notes": (context) => NotesScreen(),

                "/note": (context) => NoteScreen(),

                "/new-note": (context) => NewNoteScreen()

              },

              home: NotesScreen());

        }

      }




    7. Notes Screen

    8. import 'package:flutter/material.dart';

      import 'package:my_notes/providers/notes_manager.dart';

      import 'package:provider/provider.dart';

       

      class NotesScreen extends StatelessWidget {

        const NotesScreen({Key? key}) : super(key: key);

       

        @override

        Widget build(BuildContext context) {

          final notesManager = Provider.of<NotesManager>(context);

          final notes = notesManager.noteItems;

          return Scaffold(

            appBar: AppBar(

              title: Text("Notes (${notes.length})"),

            ),

            floatingActionButton: FloatingActionButton(

              child:const  Icon(Icons.add),

              onPressed: () {

                Navigator.of(context).pushNamed("/new-note");

              },

            ),

            body: ListView.builder(

              itemCount: notes.length,

              itemBuilder: (ctx, index) {

                return ListTile(

                  leading: Text((index + 1).toString()),

                  title: Text(notes[index].title),

                  trailing:const  Icon(Icons.remove_red_eye_outlined),

                  onTap: () {

                    Navigator.of(context).pushNamed("/note", arguments: index);

                  },

                );

              },

            ),

          );

        }

      }




    9. New Note Screen

    10. import 'package:flutter/material.dart';

      import 'package:my_notes/models/note.dart';

      import '../providers/notes_manager.dart';

      import 'package:provider/provider.dart';

       

      class NewNoteScreen extends StatelessWidget {

        NewNoteScreen({Key? key}) : super(key: key);

       

        final _formKey = GlobalKey<FormState>();

        final TextEditingController _titleController = TextEditingController();

        final TextEditingController _descriptionController = TextEditingController();

       

        @override

        Widget build(BuildContext context) {

          return Scaffold(

            appBar: AppBar(

              title: const Text("New Note"),

            ),

            body: Padding(

              padding: const EdgeInsets.all(10),

              child: Form(

                key: _formKey,

                child: Column(

                  children: [

                    TextFormField(

                      decoration: const InputDecoration(hintText: "Title"),

                      validator: (value) {

                        if (value == null || value.isEmpty) {

                          return "Please enter a title";

                        }

                        return null;

                      },

                      controller: _titleController,

                    ),

                    TextFormField(

                      decoration: const InputDecoration(hintText: "Description"),

                      validator: (value) {

                        if (value == null || value.isEmpty) {

                          return "Please enter a description";

                        }

                        return null;

                      },

                      controller: _descriptionController,

                    ),

                    ElevatedButton(

                        onPressed: () {

                          if (_formKey.currentState!.validate()) {

                            Note newNote = Note(

                                _titleController.text, _descriptionController.text);

                            final notesManager =

                                Provider.of<NotesManager>(context, listen: false);

                            notesManager.addNote(newNote);

                            Navigator.of(context).pop();

                          }

                        },

                        child: const Text("Add"))

                  ],

                ),

              ),

            ),

          );

        }

      }




    11. Note Screen

    12. import 'package:flutter/material.dart';

      import 'package:my_notes/providers/notes_manager.dart';

      import 'package:provider/provider.dart';

       

      class NoteScreen extends StatelessWidget {

        NoteScreen({Key? key}) : super(key: key);

       

        @override

        Widget build(BuildContext context) {

          final noteIndex = ModalRoute.of(context)!.settings.arguments as int;

          final noteProvider = Provider.of<NotesManager>(context, listen: false);

          final note = noteProvider.geNoteByIndex(noteIndex);

          return Scaffold(

            appBar: AppBar(

              title: const Text("Note"),

            ),

            body: ListTile(

              title: Text(note.title),

              subtitle: Text(note.description),

            ),

            floatingActionButton: FloatingActionButton(

              child: const Icon(Icons.delete),

              backgroundColor: Colors.red,

              onPressed: () {

                noteProvider.deleteNote(noteIndex);

                Navigator.of(context).pop();

              },

            ),

          );

        }

      }


    Preview :



Code Source :

github