#100DaysOfCodeChallenge - Crop Management Information System - Day 5

Recap

On day 4 we paused building the crop management information system and discussed layout and constraints when using Row and Columns.

Overview

In this post we will refactor the Farmer Registration Form to make the code more readable.

Going deeper

The farmer registration form is show below. Farmer Form

AddFarmerScreen

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();
}

_AddFarmerScreenController

We'll discuss this widget in depth when we connect the AddFarmerCommand to the Form.

_AddFarmerScreenView

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.

Wrap UP

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.

Connect with me

Thank you for reading my post. Feel free to subscribe below to join me on the #100DaysOfCodeChallenge or connect with me on LinkedIn and Twitter.

43