If you don't understand the concept of widgets, you can refer to our Flutter From Scratch video on this topic.
How do you use this Flutter widgets cheat sheet? Just copy-paste the code for the widgets you want to use in your app, and modify it to incorporate the logic you need. Let's get started!
Interaction widgets make your application dynamic and provide a good user experience, so it's essential to understand how to use them.
GestureDetector is a widget that responds to events or gestures that correspond to its non-callbacks.
You can use this gesture detector to create custom buttons or clickable text or pictures.
To add a gesture detector, use the code below:
GestureDetector( onTap: () < const snackBar = SnackBar(content: Text('Tap')); ScaffoldMessenger.of(context).showSnackBar(snackBar); >, // The custom button child: Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: Colors.lightBlue, borderRadius: BorderRadius.circular(8.0), ), child: const Text('My Button'), ), )
Enter fullscreen mode
Exit fullscreen mode
The AlertDialog widget creates a window to display crucial information with options that allow the user to make decisions.
To add an alert dialog to your app, you can use the following code:
Future _showMyDialog() async < return showDialog( context: context, barrierDismissible: false, // user must tap button! builder: (BuildContext context) < return AlertDialog( title: const Text('Cheat Sheet'), content: SingleChildScrollView( child: ListBody( children: const [ Text('This is a demo alert dialog.'), Text('Would you like to approve of this message?'), ], ), ), actions: [ TextButton( child: const Text('Approve'), onPressed: () < Navigator.of(context).pop(); >, ), ], ); >, ); >
Enter fullscreen mode
Exit fullscreen mode
The SnackBar widget is used to briefly tell a user that an action has taken place. For example, you can delete an item that triggers a snackbar, which tells the user that an item has just been deleted.
To add a snackbar to your application, use the code below:
Center( child: ElevatedButton( onPressed: () < final snackBar = SnackBar( content: const Text('Yay! A SnackBar!'), action: SnackBarAction( label: 'Undo', onPressed: () < Text('data'); >, ), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); >, child: const Text('Show snackbar'), ), ),
Enter fullscreen mode
Exit fullscreen mode
You can use a Dismissable widget to remove or dismiss items from a list. You can swipe left or right to remove any item.
Use the code below to implement this feature:
List items = [ 'banana', 'strawberry', 'apple' 'orange' 'cat' 'bobcat' ]; ListView.builder( itemCount: items.length, padding: const EdgeInsets.symmetric(vertical: 16), itemBuilder: (BuildContext context, index) < return Dismissible( background: Container( color: Colors.green, ), key: Key(items[index]), onDismissed: (DismissDirection direction) < setState(() < items.removeAt(index); >); >, child: ListTile( title: Text( 'Item $', ), ), ); >, ),
Enter fullscreen mode
Exit fullscreen mode
If you have a big picture that doesn't fit on the screen, you can use the InteractiveViewer widget to enable it to fit on the screen by allowing the user to zoom in and out of the picture.
InteractiveViewer( boundaryMargin: const EdgeInsets.all(20.0), child: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.blue, Colors.yellow], stops: [0.0, 1.0], ), ), ), ),
Enter fullscreen mode
Exit fullscreen mode
Input widgets are a very important part of modern-day Flutter applications. For example, they are used to create an account, log in, or even perform a simple search.
You can create a login and signup form using these widgets.
Try creating a form using the Forms widget and TextFormFields widget:
class MyApp extends StatelessWidget < const MyApp() : super(key: key); @override Widget build(BuildContext context) < const appTitle = 'Flutter Form Demo'; return MaterialApp( title: appTitle, home: Scaffold( appBar: AppBar( title: const Text(appTitle), ), body: const MyCustomForm(), ), ); >> // Create a Form widget class MyCustomForm extends StatefulWidget < const MyCustomForm() : super(key: key); @override MyCustomFormState createState() < return MyCustomFormState(); >> class MyCustomFormState extends State < final formKey = GlobalKey(); @override Widget build(BuildContext context) < // Build a Form widget using the formKey created above return Form( key: formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( decoration: const InputDecoration( icon: Icon(Icons.person), hintText: 'Enter your name', labelText: 'Name', ), ), TextFormField( decoration: const InputDecoration( icon: Icon(Icons.calendar_today), hintText: 'Enter your date of birth', labelText: 'Dob', ), ), const ElevatedButton( child: Text('Submit'), onPressed: null, ), ], ), ); > >
Enter fullscreen mode
Exit fullscreen mode
This widget can come in handy in search boxes.
To add autocomplete to your Flutter application, you can use the following code snippet. The options to be displayed are determined by the optionsBuilder and rendered by the optionsViewBuilder .
// have a list of words or names from a remote source or package const List _kOptions = [ 'aardvark', 'bobcat', 'chameleon', ]; // use the Autocomplete widget to make selections Autocomplete( optionsBuilder: (TextEditingValue textEditingValue) < if (textEditingValue.text == '') < return const Iterable.empty(); > return _kOptions.where((String option) < return option.contains(textEditingValue.text.toLowerCase()); >); >, onSelected: (String selection) < debugPrint('You just selected $selection'); >, );
Enter fullscreen mode
Exit fullscreen mode
TextField is one of the most fundamental and commonly used widgets for keyboard input.
TextField( obscureText: true, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password', ), )
Enter fullscreen mode
Exit fullscreen mode
These widgets are very important for building UIs in Flutter.
This widget centers a child within itself.
Center( child: Text('Center me'))
Enter fullscreen mode
Exit fullscreen mode
The Expanded widget expands the child of a Row or Column to fill any available space.
For example, you can use it to build a UI that fills the screen with just three containers or pictures. Theoretically, we can just specify their heights, but remember that there are different screen sizes for different devices, including tablets such as iPad devices. The expanded widget can help you create a more responsive design that can easily fit all screen sizes.
Row( children: [ Expanded( flex: 2, child: Container( color: Colors.amber, height: 100, ), ), Container( color: Colors.blue, height: 100, width: 50, ), Expanded( child: Container( color: Colors.amber, height: 100, ), ), ], ),
Enter fullscreen mode
Exit fullscreen mode
The Align widget aligns its child within itself. This widget is very flexible and can take the size of its child.
The child can be placed at different points within its parent widget using the alignment property , as shown below:
Container( height: 120.0, width: 120.0, color: Colors.blue[50], child: const Align( alignment: Alignment.topRight, child: FlutterLogo( size: 60, ), ), ),
Enter fullscreen mode
Exit fullscreen mode
The Row widget takes a list of widgets and arranges them horizontally. You will likely use this widget a lot when making layouts in your code.
Row( children: [ ElevatedButton( child: const Text('Widget 1'), onPressed: () => Navigator.pushNamed(context, '/second'), ), ElevatedButton( child: const Text('Widget 2'), onPressed: () => Navigator.pushNamed(context, '/third'), ), ElevatedButton( child: const Text('Widget 3'), onPressed: () => Navigator.pushNamed(context, '/fourth'), ), ], ),
Enter fullscreen mode
Exit fullscreen mode
The Column widget allows you to arrange a list of widgets vertically, similar to how the Row widget aligns them horizontally.
Column( children: const [ Text('Deliver features faster'), Text('Craft beautiful UIs'), Expanded( child: FittedBox( fit: BoxFit.contain, child: FlutterLogo(), ), ), ], )
Enter fullscreen mode
Exit fullscreen mode
Use SizedBox to give a specific size to its child widget or provide some white space between widgets.
const SizedBox( width: 200.0, height: 300.0, child: Card(child: Text('Size me!')), )
Enter fullscreen mode
Exit fullscreen mode
Use the BaseLine widget to position the child widget according to the starting point of the parent widget.
Center( child: Container( width: 100, height: 100, color: Colors.green, child: Baseline( baseline: 50, baselineType: TextBaseline.ideographic, child: Container( width: 50, height: 50, color: Colors.purple, ), ), ), );
Enter fullscreen mode
Exit fullscreen mode
Use this widget to assign a default size to a list of widgets that are unconstrained.
LimitedBox( maxHeight: 150, maxWidth: 150, child: Container( color: Colors.red, ) )
Enter fullscreen mode
Exit fullscreen mode
Use the Padding widget to provide space around its child. The padding widget adds space around its child using the abstract EdgeInsetsGeometry class.
The padding property of the padding widget accepts the EdgeInsets object, which allows you to add different types of padding, including padding only in certain places using EdgeInsets.only or from different angles using EdgeInsets.fromLTRB .
const Card( child: Padding( padding: EdgeInsets.all(16.0), child: Text('Hello World!'), ), )
Enter fullscreen mode
Exit fullscreen mode
ListView Builder is the most used scrollable widget. It displays its children in the scroll direction one after the other. For example, if you have a long list that is dynamically created, you can use Listview.builder to display it.
Use the following code to get started:
final List entries = ['A', 'B', 'C']; ListView.builder( padding: const EdgeInsets.all(8), itemCount: entries.length, itemBuilder: (BuildContext context, int index) < return Container( height: 50, color: Colors.amber[colorCodes[index]], child: Center(child: Text('Entry $')), ); >
Enter fullscreen mode
Exit fullscreen mode
The SingleChildScrollView widget will come in handy if you have a list of items that you initially didn't intend for the user to scroll through, but the requirements change upon implementation. In this case, you can quickly wrap the parent widget with a SingleChildScrollView to make it scrollable.
SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( color: Colors.red, height: 300.0, alignment: Alignment.center, child: const Text('Fixed Height Content'), ), Container( color: Colors.blue, height: 250.0, alignment: Alignment.center, child: const Text('Fixed Height Content'), ), Container( color: Colors.green, height: 250.0, alignment: Alignment.center, child: const Text('Fixed Height Content'), ), Container( color: Colors.purple, height: 250.0, alignment: Alignment.center, child: const Text('Fixed Height Content'), ), ], ), );
Enter fullscreen mode
Exit fullscreen mode
These are the widgets that compose your app. In this Flutter widget cheat sheet, we will only be highlighting two of them: Scaffold and Loader.
Use Scaffold widgets for all your application layers.
Scaffold( appBar: AppBar(), body: Row( children: [ ElevatedButton( child: const Text('Widget 1'), onPressed: () => Navigator.pushNamed(context, '/second'), ), ),
Enter fullscreen mode
Exit fullscreen mode
Create Loaders for your app when making an API request.
class SomeWidget extends StatefulWidget < @override _SomeWidgetState createState() =>_SomeWidgetState(); > class _SomeWidgetState extends State < late Future future; @override void initState() < future = Future.delayed(const Duration(seconds: 8)); super.initState(); >@override Widget build(BuildContext context) < return FutureBuilder( future: future, builder: (context, snapshot) < return snapshot.connectionState == ConnectionState.done ? const Text('Loaded') : const CircularProgressIndicator(); >, ); > >
Enter fullscreen mode
Exit fullscreen mode
Painting effects can give a finished look to your app's design.
With the InkWell widget, you can create ink splash effects on images or custom buttons when you click on them.
class _SomeWidgetState extends State < @override Widget build(BuildContext context) < Image img = Image.network( 'https://images.unsplash.com/photo-1592194996308-7b43878e84a6?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80'); return Material( child: Ink.image( fit: BoxFit.fill, width: 300, height: 300, image: img.image, child: InkWell( onTap: () < print('image'); >, child: const Align( child: Padding( padding: EdgeInsets.all(10.0), child: Text( 'PUFFIN', style: TextStyle( fontWeight: FontWeight.w900, color: Colors.white, ), ), ), ), ), ), ); > >
Enter fullscreen mode
Exit fullscreen mode
DecoratedBox, together with BoxDecoration, helps you add more styling to your container widget.
Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(12), ), gradient:RadialGradient( center: Alignment(-0.5, -0.6), radius: 0.15, colors: [ Color(0xFFEEEEEE), Color(0xFF111133), ], stops: [0.9, 1.0], )));
Enter fullscreen mode
Exit fullscreen mode
Use ClipRect to clip the child within different shapes.
class DecorateContainer extends StatelessWidget < const DecorateContainer(Key? key, this.image) : super(key: key); final Image image; @override Widget build(BuildContext context) < return ClipRect( child: Container( child: Align( alignment: Alignment.center, widthFactor: 0.4, heightFactor: 1.0, child: image ), ), ); >>
Enter fullscreen mode
Exit fullscreen mode
With the ClipPath widget, you can give any shape to the child widget. This means you can use it to draw any shape of your choice or according to your UI requirements with less code.
// body of your app ClipPath( child: Container( width: MediaQuery.of(context).size.width, height: 250, color: Colors.red, ), clipper: CustomClipPath(), ), // custom class class CustomClipPath extends CustomClipper < var radius=5.0; @override Path getClip(Size size) < Path path = Path(); path.lineTo(size.width / 2, size.height); path.lineTo(size.width, 0.0); return path; >@override bool shouldReclip(CustomClipper oldClipper) => false; >
Enter fullscreen mode
Exit fullscreen mode
There are many types of buttons in Flutter, so we'll only suggest the most useful ones in this cheat sheet.
This is a Material button with text that has no borders.
TextButton( style: TextButton.styleFrom( padding: const EdgeInsets.all(16.0), primary: Colors.white, textStyle: const TextStyle(fontSize: 20), ), onPressed: () <>, child: const Text('Gradient'), ),
Enter fullscreen mode
Exit fullscreen mode
ElevatedButton is a Material button that elevates when pressed. Avoid using elevated buttons on widgets that are already elevated, like dialogs.
ElevatedButton( style: ElevatedButton.styleFrom(), onPressed: () <>, child: const Text('Enabled'), ),
Enter fullscreen mode
Exit fullscreen mode
Use FloatingActionButton to create a primary action on the screen.
Scaffold( appBar: AppBar( title: const Text('Floating Action Button'), ), body: const Center(child: Text('Press the button below!')), floatingActionButton: FloatingActionButton( onPressed: () < // on pressed >, backgroundColor: Colors.green, child: const Icon(Icons.navigation), ), );
Enter fullscreen mode
Exit fullscreen mode
Named routing can be used for small to medium-sized projects. Alternatively, you can use the Navigator API, which provides various routing functions.
Flutter provides named routing to enable users to navigate your application:
void main() < runApp(MaterialApp( initialRoute: '/', routes: < '/' : ((context) =>const FirstScreen()), '/second':(context) => const SecondScreen() >, home: const MyApp())); > class MyApp extends StatelessWidget < const MyApp() : super(key: key); @override Widget build(BuildContext context) < return Scaffold( appBar: AppBar( title: const Text('Navigation'), ), body:const FirstScreen() ); >> class FirstScreen extends StatelessWidget < const FirstScreen() : super(key: key); @override Widget build(BuildContext context) < return Center( child: ElevatedButton( child: const Text('Go to SecondScreen'), onPressed: () =>Navigator.pushNamed(context, '/second'), ), ); > > // can add this in a new file class SecondScreen extends StatelessWidget < const SecondScreen() : super(key: key); @override Widget build(BuildContext context) < return ElevatedButton( child:const Text('Go back!'), onPressed: () =>Navigator.pop(context), ); > >
Enter fullscreen mode
Exit fullscreen mode
To learn more about Flutter Navigator 2.0, read this article.
We have created this list of Flutter widgets as a quick reference for you while you build your Flutter app. We hope you have learned something new about these widgets that can help you improve the functionality of your Flutter application.
We have an ebook that covers a list of libraries commonly used by Flutter developers, including networking, state management, and more. You can also watch our Flutter From Scratch tutorial, which goes into detail about how to use these libraries and widgets.
Codemagic is a CI/CD tool for Flutter and other mobile developers.