App9 : To-Do List - Learning New Widgets



  1. Drawer
  2. A material design panel that slides in horizontally from the edge of a Scaffold to show navigation links in an application.

    Drawers are typically used with the Scaffold.drawer property. The child of the drawer is usually a ListView whose first child is a DrawerHeader that displays status information about the current user. The remaining drawer children are often constructed with ListTiles, often concluding with an AboutListTile.

    The AppBar automatically displays an appropriate IconButton to show the Drawer when a Drawer is available in the Scaffold. The Scaffold automatically handles the edge-swipe gesture to show the drawer.

    Example :


    import 'package:flutter/material.dart';

     

    void main() => runApp(const MyApp());

     

    class MyApp extends StatelessWidget {

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

     

      @override

      Widget build(BuildContext context) {

        return MaterialApp(

            title: 'Flutter Drawer Example',

            home: const HomePage(),

            routes: {

              "/page1": (context) => const PageOne(),

              "/page2": (context) => const PageTwo(),

              "/page3": (context) => const PageThree()

            });

      }

    }

     

    class HomePage extends StatefulWidget {

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

     

      @override

      HomePageState createState() {

        return HomePageState();

      }

    }

     

    class HomePageState extends State<HomePage> {

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text('Flutter Drawer Example'),

          ),

          body: const Center(

            child: Text("Main Page"),

          ),

          drawer: Drawer(

            child: ListView(

              padding: EdgeInsets.zero,

              children: [

                DrawerHeader(

                    decoration: const BoxDecoration(color: Colors.blue),

                    child: Container(

                        alignment: Alignment.center,

                        child: const Text(

                          "Pages",

                          style: TextStyle(color: Colors.white, fontSize: 28),

                        ))),

                ListTile(

                  leading: const Icon(Icons.one_k),

                  title: const Text("Page 1"),

                  onTap: () {

                    Navigator.pop(context); // close the drawer

                    Navigator.pushNamed(context, "/page1");

                  },

                ),

                ListTile(

                  leading: const Icon(Icons.two_k),

                  title: const Text("Page 2"),

                  onTap: () {

                    Navigator.pop(context); // close the drawer

                    Navigator.pushNamed(context, "/page2");

                  },

                ),

                ListTile(

                  leading: const Icon(Icons.three_k),

                  title: const Text("Page 3"),

                  onTap: () {

                    Navigator.pop(context); // close the drawer

                    Navigator.pushNamed(context, "/page3");

                  },

                )

              ],

            ),

          ),

        );

      }

    }

     

    class PageOne extends StatelessWidget {

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

     

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text("Page 1"),

          ),

          body: const Center(

            child: Text("Page 1"),

          ),

        );

      }

    }

     

    class PageTwo extends StatelessWidget {

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

     

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text("Page 2"),

          ),

          body: const Center(

            child: Text("Page 2"),

          ),

        );

      }

    }

     

    class PageThree extends StatelessWidget {

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

     

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text("Page 3"),

          ),

          body: const Center(

            child: Text("Page 3"),

          ),

        );

      }

    }




  3. SnackBar
  4. A lightweight message with an optional action which briefly displays at the bottom of the screen.

    To display a snack bar, call ScaffoldMessenger.of(context).showSnackBar(), passing an instance of SnackBar that describes the message.

    To control how long the SnackBar remains visible, specify a duration.

    A SnackBar with an action will not time out when TalkBack or VoiceOver are enabled. This is controlled by AccessibilityFeatures.accessibleNavigation.

    Some properties of SnackBar Class:

    1. duration : Duration
    2. The amount of time the snack bar should be displayed.

    3. content : Widget
    4. The primary content of the snack bar.

    5. backgroundColor : Color?
    6. The snack bar's background color.

    7. action : SnackBarAction?
    8. (optional) An action that the user can take based on the snack bar.



    Example :


     

    class HomePage extends StatefulWidget {

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

     

      @override

      HomePageState createState() {

        return HomePageState();

      }

    }

     

    class HomePageState extends State<HomePage> {

      Color c = Colors.white;

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text('Flutter SnackBar Example'),

          ),

          backgroundColor: c,

          body: Center(

            child: OutlinedButton(

              child: Text("Show SnackBar"),

              onPressed: () {

                ScaffoldMessenger.of(context).showSnackBar(SnackBar(

                  content: const Text("Change Background Color ?"),

                  duration: Duration(seconds: 2),

                  action: SnackBarAction(

                    label: "Yes!",

                    onPressed: () {

                      // Code to execute

                      setState(() {

                        c = Colors.yellowAccent;

                      });

                    },

                  ),

                ));

              },

            ),

          ),

        );

      }

    }





  5. AlertDialog
  6. An alert dialog informs the user about situations that require acknowledgement. An alert dialog has an optional title and an optional list of actions. The title is displayed above the content and the actions are displayed below the content.

    If the content is too large to fit on the screen vertically, the dialog will display the title and the actions and let the content overflow, which is rarely desired. Consider using a scrolling widget for content, such as SingleChildScrollView, to avoid overflow. (However, be aware that since AlertDialog tries to size itself using the intrinsic dimensions of its children, widgets such as ListView, GridView, and CustomScrollView, which use lazy viewports, will not work. If this is a problem, consider using Dialog directly.)

    For dialogs that offer the user a choice between several options, consider using a SimpleDialog.

    Typically passed as the child widget to showDialog, which displays the dialog.

    Some properties of AlertDialog Class:

    1. actions : List<Widget>?
    2. The (optional) set of actions that are displayed at the bottom of the dialog with an OverflowBar.

    3. content : Widget
    4. The (optional) content of the dialog is displayed in the center of the dialog in a lighter font.

    5. backgroundColor : Color?
    6. The background color of the surface of this Dialog.

    7. elevation : double?
    8. The z-coordinate of this Dialog.

    9. title : Widget?
    10. The (optional) title of the dialog is displayed in a large font at the top of the dialog.



    Example :


     

    class HomePage extends StatefulWidget {

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

     

      @override

      HomePageState createState() {

        return HomePageState();

      }

    }

     

    class HomePageState extends State<HomePage> {

      Color c = Colors.white;

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text('Flutter AlertDialog Example'),

          ),

          backgroundColor: c,

          body: Center(

            child: OutlinedButton(

              child: const Text("Show AlertDialog"),

              onPressed: () {

                showDialog<String>(

                  context: context,

                  builder: (BuildContext context) => AlertDialog(

                    title: const Text('Are You Sure ?'),

                    content: const Text('AlertDialog description'),

                    actions: <Widget>[

                      TextButton(

                        onPressed: () => Navigator.pop(context),

                        child: const Text('Cancel'),

                      ),

                      TextButton(

                        onPressed: () => Navigator.pop(context),

                        child: const Text('OK'),

                      ),

                    ],

                  ),

                );

              },

            ),

          ),

        );

      }

    }




  7. Chip
  8. A material design chip.

    Chips are compact elements that represent an attribute, text, entity, or action.

    Supplying a non-null onDeleted callback will cause the chip to include a button for deleting the chip.

    Some properties of Chip Class:

    1. avatar : Widget?
    2. A widget to display prior to the chip's label.

    3. label : Widget
    4. The primary content of the chip.

    5. backgroundColor : Color?
    6. Color to be used for the unselected, enabled chip's background.

    7. labelStyle : TextStyle?
    8. The style to be applied to the chip's label.

    9. side : BorderSide?
    10. The color and weight of the chip's outline.



    Example :


     

    class HomePage extends StatelessWidget {

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

      Color c = Colors.white;

      @override

      Widget build(BuildContext context) {

        return Scaffold(

          appBar: AppBar(

            title: const Text('Flutter Chip Example'),

          ),

          backgroundColor: c,

          body: Center(

              child: Row(

            mainAxisAlignment: MainAxisAlignment.spaceAround,

            children: const [

              Chip(

                avatar: Icon(Icons.phone_android),

                backgroundColor: Color.fromRGBO(185, 1, 1, 0.2),

                labelStyle:

                    TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),

                side: BorderSide(color: Colors.blue),

                label: Text('Phone'),

              ),

              Chip(

                avatar: Icon(Icons.computer_outlined),

                backgroundColor: Color.fromRGBO(18, 190, 13, 0.2),

                label: Text('Laptop'),

              ),

              Chip(

                avatar: Icon(Icons.tablet_mac),

                backgroundColor: Color.fromRGBO(13, 14, 170, 0.2),

                label: Text('Tablet'),

              ),

            ],

          )),

        );

      }

    }



    Flutter Chip

  9. Radio
  10. Used to select between a number of mutually exclusive values. When one radio button in a group is selected, the other radio buttons in the group cease to be selected. The values are of type T, the type parameter of the Radio class. Enums are commonly used for this purpose.

    The radio button itself does not maintain any state. Instead, selecting the radio invokes the onChanged callback, passing value as a parameter. If groupValue and value match, this radio will be selected. Most widgets will respond to onChanged by calling State.setState to update the radio button's groupValue.

    Some properties of Radio Class:

    1. activeColor : Color?
    2. The color to use when this radio button is selected.

    3. groupValue : T?
    4. The currently selected value for a group of radio buttons.

    5. onChanged : ValueChanged?
    6. Called when the user selects this radio button.

    7. value : T
    8. The value represented by this radio button.



    Example :


     

    class HomePage extends StatefulWidget {

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

     

      @override

      State<HomePage> createState() => _HomePageState();

    }

     

    enum MainColors { red, blue, green }

    enum Sizes { S, M, L }

     

    class _HomePageState extends State<HomePage> {

      MainColors? _color = MainColors.red;

      Sizes? _size = Sizes.S;

     

      @override

      Widget build(BuildContext context) {

        return Scaffold(

            appBar: AppBar(

              title: const Text('Flutter Radio Example'),

            ),

            body: Padding(

              padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),

              child: Column(

                children: <Widget>[

                  Text("Your Color : ${_color}"),

                  const SizedBox(height: 40),

                  ListTile(

                    title: const Text('Red'),

                    leading: Radio<MainColors>(

                      value: MainColors.red,

                      groupValue: _color,

                      onChanged: (MainColors? value) {

                        setState(() {

                          _color = value;

                        });

                      },

                    ),

                  ),

                  ListTile(

                    title: const Text('Blue'),

                    leading: Radio<MainColors>(

                      value: MainColors.blue,

                      groupValue: _color,

                      onChanged: (MainColors? value) {

                        setState(() {

                          _color = value;

                        });

                      },

                    ),

                  ),

                  ListTile(

                    title: const Text('Green'),

                    leading: Radio<MainColors>(

                      value: MainColors.green,

                      groupValue: _color,

                      onChanged: (MainColors? value) {

                        setState(() {

                          _color = value;

                        });

                      },

                    ),

                  ),

                  const SizedBox(height: 80),

                  Text("Your Size : ${_size}"),

                  const SizedBox(height: 40),

                  ListTile(

                    title: const Text('S'),

                    leading: Radio<Sizes>(

                      value: Sizes.S,

                      groupValue: _size,

                      onChanged: (Sizes? value) {

                        setState(() {

                          _size = value;

                        });

                      },

                    ),

                  ),

                  ListTile(

                    title: const Text('M'),

                    leading: Radio<Sizes>(

                      value: Sizes.M,

                      groupValue: _size,

                      onChanged: (Sizes? value) {

                        setState(() {

                          _size = value;

                        });

                      },

                    ),

                  ),

                  ListTile(

                    title: const Text('L'),

                    leading: Radio<Sizes>(

                      value: Sizes.L,

                      groupValue: _size,

                      onChanged: (Sizes? value) {

                        setState(() {

                          _size = value;

                        });

                      },

                    ),

    pa

                  )

                ],

              ),

            ));

      }

    }





  11. PopupMenuButton
  12. Displays a menu when pressed and calls onSelected when the menu is dismissed because an item was selected. The value passed to onSelected is the value of the selected menu item.

    One of child or icon may be provided, but not both. If icon is provided, then PopupMenuButton behaves like an IconButton.

    If both are null, then a standard overflow icon is created (depending on the platform).

    Some properties of PopupMenuButton Class:

    1. child : Widget?
    2. If provided, child is the widget used for this button and the button will utilize an InkWell for taps.

    3. color : Color?
    4. If provided, the background color used for the menu.

    5. icon : Widget?
    6. If provided, the icon is used for this button and the button will behave like an IconButton.

    7. iconSize : double?
    8. If provided, the size of the Icon.

    9. itemBuilder : PopupMenuItemBuilder<T>
    10. Called when the button is pressed to create the items to show in the menu.

    11. onSelected : PopupMenuItemSelected?
    12. Called when the user selects a value from the popup menu created by this button.



    Example :


     

    class HomePage extends StatefulWidget {

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

     

      @override

      State<HomePage> createState() => _HomePageState();

    }

     

    class _HomePageState extends State<HomePage> {

      Color _color = Colors.yellow;

      @override

      Widget build(BuildContext context) {

        return Scaffold(

            appBar: AppBar(

              title: const Text('Flutter PopupMenuButton Example'),

            ),

            body: Center(

                child: ListTile(

              leading: Icon(

                Icons.star,

                color: _color,

              ),

              title: const Text("Favorite Color"),

              trailing: PopupMenuButton<Color>(

                icon: const Icon(Icons.edit),

                iconSize: 20,

                color: Color.fromRGBO(220, 220, 120, 0.2),

                onSelected: (Color result) {

                  setState(() {

                    _color = result;

                  });

                },

                itemBuilder: (BuildContext context) => <PopupMenuEntry<Color>>[

                  const PopupMenuItem<Color>(

                    value: Colors.red,

                    child: Text('Change To Red'),

                  ),

                  const PopupMenuItem<Color>(

                    value: Colors.blue,

                    child: Text('Change To Blue'),

                  ),

                  const PopupMenuItem<Color>(

                    value: Colors.green,

                    child: Text('Change To Green'),

                  ),

                  const PopupMenuItem<Color>(

                    value: Colors.black,

                    child: Text('Change To Black'),

                  ),

                ],

              ),

            )));

      }

    }





  13. ExpansionPanel
  14. A material expansion panel. It has a header and a body and can be either expanded or collapsed. The body of the panel is only visible when it is expanded.

    Expansion panels are only intended to be used as children for ExpansionPanelList.

    Some properties of ExpansionPanel Class:

    1. backgroundColor : Color?
    2. Defines the background color of the panel.

    3. body : Widget
    4. The body of the expansion panel that's displayed below the header.

    5. canTapOnHeader : bool
    6. Whether tapping on the panel's header will expand/collapse it.

    7. isExpanded : bool
    8. Whether the panel is expanded.

    9. headerBuilder : ExpansionPanelHeaderBuilder
    10. The widget builder that builds the expansion panels' header.



    Example :


     

    class HomePage extends StatefulWidget {

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

     

      @override

      State<HomePage> createState() => _HomePageState();

    }

     

    class _HomePageState extends State<HomePage> {

      List<bool> isOpen = [false, false, false];

      @override

      Widget build(BuildContext context) {

        return Scaffold(

            appBar: AppBar(

              title: const Text('Flutter ExpansionPanel Example'),

            ),

            body: Padding(

              padding: const EdgeInsets.all(16.0),

              child: SingleChildScrollView(

                child: ExpansionPanelList(

                  expansionCallback: (int index, bool isExpanded) {

                    setState(() {

                      isOpen[index] = !isOpen[index];

                    });

                  },

                  children: [

                    ExpansionPanel(

                        isExpanded: isOpen[0],

                        headerBuilder: (ctx, isOpen) {

                          return const ListTile(

                              title: Text("The standard Lorem Ipsum"));

                        },

                        body: const ListTile(

                          subtitle: Text(

                              "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."),

                        )),

                    ExpansionPanel(

                        isExpanded: isOpen[1],

                        headerBuilder: (ctx, isOpen) {

                          return const ListTile(

                              title: Text("1914 translation by H. Rackham"));

                        },

                        body: const ListTile(

                            subtitle: Text(

                                "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain."))),

                    ExpansionPanel(

                        isExpanded: isOpen[2],

                        headerBuilder: (ctx, isOpen) {

                          return const ListTile(title: Text("Section 1.10.33"));

                        },

                        body: const ListTile(

                            subtitle: Text(

                                "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti.")))

                  ],

                ),

              ),

            ));

      }

    }