flutterdartflutter-layoutcustom-widgets

Adding custom widget dynamically to a list - Flutter


I have a simple custom widget trans() (short for transaction) that just takes a number and a Boolean and displays a row, and I have a list:

 List<trans> transactions=[
      trans(false, 20),
      trans(true, -50),
      trans(false, 110),
      trans(false, 35.5),

    ];

and display it using a ListView :

ListView.builder(
 itemCount: transactions.length,
  itemBuilder: (context, index){
  return(
  transactions[index]
  );
 },
),

But how can I add a new widget to the list using a button and update the screen dynamically ?


Solution

  • You may try the following code :

    import 'package:flutter/material.dart';
    import 'dart:math' as math;
    
    final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
    
    void main() {
      runApp(MyApp());
    }
    
    extension Ex on double {
      double toPrecision(int n) => double.parse(toStringAsFixed(n));
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            appBar: AppBar(
              title: const Text("Flutter Demo App"),
            ),
            body: Center(
              child: MyWidget(),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      _MyWidgetState createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      final List<Trans> transactions = [
        const Trans(myBool: false, myDouble: 20),
        const Trans(myBool: true, myDouble: -50),
        const Trans(myBool: false, myDouble: 110),
        const Trans(myBool: false, myDouble: 35.5),
      ];
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              height: MediaQuery.of(context).size.height * .7,
              child: Scrollbar(
                showTrackOnHover: true,
                child: ListView.builder(
                  itemCount: transactions.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: transactions[index],
                    );
                  },
                ),
              ),
            ),
            RaisedButton(
              onPressed: () {
                final rnd = math.Random();
                setState(
                  () {
                    transactions.add(
                      Trans(
                        myBool: rnd.nextBool(),
                        myDouble:
                            rnd.nextDouble().toPrecision(2) + rnd.nextInt(100),
                      ),
                    );
                  },
                );
              },
              child: const Text("Add Transaction"),
            ),
          ],
        );
      }
    }
    
    class Trans extends StatelessWidget {
      final myBool;
      final myDouble;
    
      const Trans({Key key, this.myBool, this.myDouble}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Row(
          children: [
            Text("Transaction: ${myBool.toString()}  ${myDouble.toString()}")
          ],
        );
      }
    }