Yusuf-Uluc
Yusuf-Uluc

Reputation: 1065

Add Text(Form)Field input to a list

Got a question for my Flutter App:

I have a List:

List<Item> tags = <Item>[
   Item(
     "name",
     Colors.red,
   ),
   Item(
     "Cooking",
     Colors.red,
   ),
   Item(
     "Sport",
     Colors.red,
   ),
 ];

and a TextFormField

   TextFormField(
     controller: tagController

how do I manage to add the Text I entered in the Formfield to the list? They are in different StatefulWidgets.

Upvotes: 0

Views: 756

Answers (1)

ASAD HAMEED
ASAD HAMEED

Reputation: 2890

Provider is a great stateManagement solution for flutter and I have solved you problem using provider. Follow these steps carefully to make sure you implement it correctly.

  1. Start by adding Provider to pubspec.yaml

    provider: ^4.3.3
    
  2. Create a notifier class that extends ChangeNotifier

    class ItemListNotifier extends ChangeNotifier{
    
        List<Item> tags = <Item>[
                      Item(
                          "name",
                          Colors.red,
                         ),
                      Item(
                          "Cooking",
                          Colors.red,
                         ),
                      Item(
                         "Sport",
                         Colors.red,
                          ),
                       ];
    
        void add(Item item){
    
        tags.add(item);
        notifyListeners(); //Rebuilds the Stateful widget on updating list
      }
    }
    
  3. Wrap you MaterialApp inside ChangeNotifierProvider

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
    
      return ChangeNotifierProvider<ItemListNotifier>(
    
                create: (context) => ItemListNotifier(),
                child: MaterialApp(
                title: 'Flutter Demo',
                theme: ThemeData(
                          primarySwatch: Colors.blue,
                          visualDensity: VisualDensity.adaptivePlatformDensity,
                      ),
                home: ScreenWithList(),
            )
         );
       }
    }
    
  4. Inside you statefulWidget with list named tags access the notifier's value using a Consumer that rebuilds every time the list gets updated and prevents the whole screen from rebuilding.

    class ScreenWithList extends StatefulWidget {
        @override
        _ScreenWithListState createState() => _ScreenWithListState();
     }
    
    class _ScreenWithListState extends State<ScreenWithList> {
    
    List<Item> tags = <Item>[
     Item(
        "name",
        Colors.red,
      ),
      Item(
        "Cooking",
        Colors.red,
      ),
      Item(
        "Sport",
        Colors.red,
      ),
    ];
    
     @override
     Widget build(BuildContext context) {
    
    return Scaffold(
      appBar: AppBar(),
      body: Center(child: Consumer<ItemListNotifier>(
    builder: (context, list, child) {
    
      print('Rebuilt');
      return ListView.builder(
    
          itemCount: list?.tags?.length ?? 0,
          itemBuilder: (context, index) {
        return Text(list?.tags[index]?.name ?? '');
                        }
                   );
               },
            )
        ),
       floatingActionButton: FloatingActionButton(
      child: Icon(
          Icons.arrow_forward,
        ),
      onPressed: () => Navigator.push(context, MaterialPageRoute(builder: 
       (context) => ScreenWithFormField()))
          ),
       );
     }
    }
    
  5. Now update your list from statefulWidget by using Provider to access add function of ItemListNotifier.

    FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => Provider.of<ItemListNotifier>(context, listen: false).add(Item(tagController.text.trim(), Colors.red)),
      ),
    

What's happening here?

Every time you update the list using ItemListNotifier's add method, it rebuilds the Consumer<ItemListNotifier.

Upvotes: 1

Related Questions