Flutter - Splitting App into Widgets - GeeksforGeeks

15 Jan, 2021
Splitting an app into widgets refers to the breaking up of large widgets into smaller, more manageable widgets which can be inferred as smaller chunks of codes. The principal thing here is to understand when to split a widget into smaller ones. We are going to discuss when to split a widget and methods of how to perform this.
Large Widget: Whenever we have a large widget with many nested widgets and other smaller widgets inside of it. It is advisable to split the large widgets into smaller widgets that can be managed easily.
Repeating Widgets: Sometimes we have a situation where we create some custom widget (e.g. custom Button) which we might use at many places, then also it is a good practice to split the piece of code into a separate widget. This helps us clean up extra lines of code and manage the changes to the widget in one place.
Complex Widget: There are situations when the widget might not be too large, but because of the implementation it becomes complex so to implement the complex parts separately for better understanding we might split the codes into different widgets.
1. Using Flutter Outline:
Use the Flutter Outline tool to split an app into widgets as shown below:
 Flutter Outline is present on the right-hand side as a hidden tab. After opening the tab we can see the Widget Tree of the current dart file. Right-click on the widget we want to extract -> click on Extract Widget.
Flutter Outline and Widget Tree
Give a name for the widget->Click Refactor. The widget will be extracted. We can also place the widget in another file (we have to import it if we keep it in a new file).
Extract and refactor
This will extract the widgets from the app as shown below:
Extracted Widgets
2. By Right Clicking on Widget:
Follow the below shortcut to quickly refactor the widgets in the application.
 By Right-Clicking on the Particular widget -> Refactor -> Extract Flutter Widget (we can also use shortcut Ctrl+Alt+W)
Click on Extract Flutter Widget..
 Give it a name and then click on refactor.
Give a name and Click on Refactor
Example : 
Here is an example of a Basic Calculator app that takes two numbers as input from the user and produces an output as the user clicks on any of the addition, subtraction, etc. buttons. There is only one dart file i.e. main.dart in this example.
Dart
import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';  void main() {  runApp(MyApp());}  class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      debugShowCheckedModeBanner: false,      title: 'GeeksforGeeks',      theme: ThemeData(        primarySwatch: Colors.green,      ),      home: Home(),    );  }}  class Home extends StatefulWidget {  @override  _HomeState createState() => _HomeState();}  class _HomeState extends State<Home> {  double n1, n2, op = 0; // 1st Number, 2nd Number and Output.  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('GeeksforGeeks'),      ),      body: Container(        padding: EdgeInsets.all(18),        child: Column(          children: [            Text(              'Simple Calculator',              style: TextStyle(fontSize: 24),            ),            SizedBox(              height: 15,            ),            Row(              children: [                CustomTextField(                    hint: '1st Number',                    onChanged: (s) {                      n1 = double.parse(s);                      print(n1);                    }),                SizedBox(width: 10),                CustomTextField(                    hint: '2nd Number',                    onChanged: (s) {                      n2 = double.parse(s);                      print(n2);                    })              ],            ),            SizedBox(height: 10),            Row(              mainAxisAlignment: MainAxisAlignment.spaceEvenly,              children: [                CustomButton(                    symbol: '+',                    onTap: () {                      setState(() {                        op = (n1 + n2);                      });                    }),                CustomButton(                    symbol: '-',                    onTap: () {                      setState(() {                        op = (n1 - n2);                      });                    }),                CustomButton(                    symbol: '×',                    onTap: () {                      setState(() {                        op = (n1 * n2);                      });                    }),                CustomButton(                    symbol: '÷',                    onTap: () {                      setState(() {                        if (n2 == 0)                          op = -1;                        else                          op = (n1 / n2).toDouble();                      });                    }),              ],            ),            SizedBox(height: 10),            Text(              'Output',              style: TextStyle(fontSize: 18),            ),            SizedBox(height: 5),            Container(              padding: EdgeInsets.all(10),              width: double.infinity,              height: 50,              decoration: BoxDecoration(                  color: Colors.black12,                  borderRadius: BorderRadius.circular(18)),              child: Center(                child: Text(                  op.toStringAsFixed(2),                  style: TextStyle(fontSize: 24),                ),              ),            )          ],        ),      ),    );  }}
The above lines show the main screen of the app. It comprises several in-built widgets and several custom widgets (made from in-built widgets). These widgets are below the Home widget.
The First Custom Widget is the Custom TextField which is extracted using the above methods and some fields are added in the constructor for better usage and less code. 
Dart
// This is a Custom TextField Widgetclass CustomTextField extends StatelessWidget {      // In the Constructor onChanged and hint fields are added.  const CustomTextField({Key key, this.onChanged, this.hint}) : super(key: key);      // It requires the onChanged Function  // and the hint to be Shown  final Function onChanged;  final String hint;    @override  Widget build(BuildContext context) {    return Expanded(      child: TextField(                  // onChanged Function is used here.        onChanged: onChanged,         style: TextStyle(fontSize: 18),        decoration: InputDecoration(            contentPadding: EdgeInsets.symmetric(horizontal: 20),            filled: true,            fillColor: Colors.black12,            border: OutlineInputBorder(                borderSide: BorderSide.none,                borderRadius: BorderRadius.circular(18)),                        // hint String is used here.            hintText: hint,             helperText: 'Keep it Short'),      ),    );  }}
The Second Custom Widget Used here is Custom Button which is made using the Gesture Detector.
Dart
//This is a Custom Button Widget.class CustomButton extends StatelessWidget {      // In the Constructor onTap and Symbol fields are added.  const CustomButton({Key key, this.onTap, this.symbol}) : super(key: key);      // It Requires 2 fields Symbol(to be displayed)  // and onTap Function  final String symbol;  final Function onTap;    @override  Widget build(BuildContext context) {    return GestureDetector(              // The onTap Field is used here.      onTap: onTap,       child: Container(        height: 60,        width: 60,        decoration: BoxDecoration(          shape: BoxShape.circle,          color: Colors.blueGrey,        ),        child: Center(          child: Text(                          // The Symbol is used here            symbol,             style: TextStyle(              fontSize: 35,              fontWeight: FontWeight.bold,              color: Colors.white,            ),          ),        ),      ),    );  }}
Output:
Results obtained by tapping different buttons.
android
Flutter
Flutter-widgets
Picked
Dart
Flutter
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Flutter - DropDownButton Widget
Flutter - Custom Bottom Navigation Bar
Flutter - Checkbox Widget
ListView Class in Flutter
Flutter - Flexible Widget
Flutter - DropDownButton Widget
Flutter - Custom Bottom Navigation Bar
Flutter Tutorial
Flutter - Checkbox Widget
Flutter - Flexible Widget