Refactoring Flutter Widgets into Sub widgets

Muhammad Mashood Siddiquie
Analytics Vidhya
5 min readJun 10, 2020

--

Hello Everyone today I'll be discussing the most important part of building a flutter application is code refactoring. It is very useful in every programming to break up your code into sub-parts for reusability of code, maybe you’ve created a button and you want to use the same button overall the app so you may refactor it into a separate file.

Step 1: Create a flutter project with the name ‘Code Refactoring flutter’.

Step 2: Create a project structure like below image:

Step 3: Create a home_screen.dart inside the screens folder and copy-paste the following code:

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeScreen'),
),
);
}
}

Step 4: Remove all the code from the main.dart and copy-paste the following code:

import 'package:flutter/material.dart';
import './screens/home_screen.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
theme: ThemeData(
primaryColor: Colors.deepOrangeAccent,
accentColor: Colors.amberAccent,
),
);
}
}

Step 5: let's create a body part of home_screen.dart, copy-paste the following code:

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeScreen'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Enter your name',
icon: Icon(Icons.person_pin),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
labelText: 'Enter your email',
icon: Icon(Icons.email),
),
keyboardType: TextInputType.emailAddress,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Enter your number',
icon: Icon(Icons.phone_android),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text('Save'),
),
SizedBox(
width: 5,
),
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text('Clear'),

),
],
),
)
],
),
);
}
}

Now in the above code, you can see clearly that repetition of widgets occurring several times and it’s not good to have use same widget several times as in above example text field is repeating several times raised button is repeating several times, it’s good to have these widgets in a separate file so we can use it in our overall app or maybe where we want to use it so we could be saved from repeating multiple lines of code again and again, by separating files it would be easier as we would import that file and use that widget in our files.

Step 6: First Let’s refactor the text field into a separate file, goto widgets folder inside lib and create a new file with the name app_text_field and copy-paste the following code:

import 'package:flutter/material.dart';

class AppTextField extends StatelessWidget {
final String title;
final inputType;

AppTextField({@required this.title, @required this.inputType});

@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10),
child: TextField(
keyboardType: inputType,
decoration: InputDecoration(
labelText: title,
icon: Icon(Icons.phone_android),
),
),
);
}
}

In-App text field widget whenever we use this widget in a file then we have to pass the title and input type into its constructor.

Step 7: Let’s import app_text_field.dart into home_screen.dart and copy-paste the following code:

import 'package:flutter/material.dart';
import '../widgets/app_text_field.dart';

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeScreen'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [

AppTextField(
title: 'Enter your name',
inputType: TextInputType.text,
icon: Icon(Icons.person_pin),
),
AppTextField(
title: 'Enter your email',
inputType: TextInputType.emailAddress,
icon: Icon(Icons.email),
),
AppTextField(
title: 'Enter your phone number',
inputType: TextInputType.phone,
icon: Icon(Icons.phone_android),
),


Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text('Save'),
),
SizedBox(
width: 5,
),
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text('Clear'),
),
],
),
)
],
),
);
}
}

As you can see many lines of code have been save with code refactoring and our main widget is more readable and understandable with code refactoring.

Step 8: Now come towards the raised button, as you can see they are repeated too, so we can also refactor it into a separate file, create a new file inside widgets folder with name ‘app_button.dart’ and copy-paste the following code:

import 'package:flutter/material.dart';

class AppButton extends StatelessWidget {
final title;
AppButton(this.title);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text(title),
),
);
}
}

Step 9: Let’s import app_button.dart into our home_screen.dart and replace the row like code below:

Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AppButton('Save'),
AppButton('Clear'),
],
),

Now as you could see our home_screen.dart widget has been fully refactored, readable, understandable not only for you but for other developers as well. It’s always good to refactor your code into a separate file for the reusability of code. This saves more lines of code and saves your time as well.

That’s all for today, I hope this is clear to you as it’s an important and essential part of your flutter app to refactor your code.

This will be the output of the app we just created.

Don’t forget to leave clap and follow me if you find out this most important concept into easy and simple steps. ❤

Github repo link:

Don’t Forget to star the repo and also follow me for more amazing repo on Github ❤ .

My Other two articles are mentioned below, check out those too:

  1. Forms and its validation:

https://medium.com/@mashoodsidd97/forms-and-its-validation-in-flutter-1c2b3f9c985c

2. Flutter Phone Authentication With firebase using Provider Package:

https://medium.com/@mashoodsidd97/flutter-phone-authentication-with-firebase-using-provider-package-55ffbce7c361

--

--