43
#100DaysOfCodeChallenge - Crop Management Information System - Day 5
On day 4 we paused building the crop management information system and discussed layout and constraints when using Row and Columns.
In this post we will refactor the Farmer Registration Form to make the code more readable.
This screen is a stateful widget with an _AddFarmerScreenController()
to manage state.
class AddFarmerScreen extends StatefulWidget {
static String routeName = 'AddFarmerPage';
const AddFarmerScreen({
Key? key,
}) : super(key: key);
_AddFarmerscreenController createState() => _AddFarmerscreenController();
}
We'll discuss this widget in depth when we connect the AddFarmerCommand
to the Form.
This is a stateless widget that is only concerned with layout. All the logic of this screen will be handled by the _AddFarmerScreenController()
.
class _AddFarmerScreenView
extends WidgetView<AddFarmerScreen, _AddFarmerscreenController> {
final state;
const _AddFarmerScreenView(this.state) : super(state);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add Farmer'),
),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Form(
key: state._formkey,
onChanged: state._hanldeOnFormChanged,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FormHeader(title: 'Farmer Registration Form'),
Expanded(
child: ListView(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
registrationNumberTextFormField(),
Spacer(),
nationalIdTextFormField(),
],
),
Row(
children: [
Expanded(
child: Column(
// mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
height: 300,
width: 300,
child: Container(
color: Colors.blue,
),
),
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.camera_alt_outlined),
label: Text('Take Picture')),
],
),
),
SizedBox(width: 30.0),
Expanded(
child: Column(children: [
firstNameTextFormField(),
nicknameTextFormField(),
lastNameTextFormField(),
]),
)
],
),
SizedBox(
height: 15,
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
dateOfBirthDatePickerFormField(),
Spacer(),
genderDropdownFormField(),
Spacer(),
ethnicityDropdownFormField(),
Spacer(),
maritalStatusDropdownFormField(),
],
),
addressTextFormField(),
Row(
children: [
farmerCategoryDropdownFormField(),
Spacer(),
subsectorDropdownFormField(),
Spacer(),
operationScaleDropdownFormField(),
],
),
Row(
children: [
headOfHouseholdCheckBoxFormField(),
farmingPrimaryIncomeSourceCheckboxFormField(),
activeFarmerCheckboxFormField(),
],
),
SizedBox(
height: 15,
),
ElevatedButton(
onPressed: () {}, child: Text('Register Farmer'))
]),
)
],
)),
),
)
For readability the form field widgets were extracted into their own function. This makes the code leaner resulting in increase readability. This is the recommended approach by flutter, read more in this article.
When your screen have multiple deeply nested widgets. Extract appropriate widgets into their own variable or functions. Extract widgets into a separate class if widgets will be reused in another part of your app. In the next post we will connect the AddFarmerCommand().run()
that was created on Day 2 along with other logics to our form layout.
43