DEV Community

Abdullah Shahid
Abdullah Shahid

Posted on

The perfect flutter boiler plate and state management solution does not exi….

Yo, yo, yo, 148–3 to the 3 to the 6 to the 9, representing the FLUTTER. What’s up?!
As you may know, flutter is the new sexy in mobile app development.

Just Do it Meme

Flutter is an open-source mobile application development framework created by Google. It allows developers to build high-performance, cross-platform apps for both Android and iOS platforms using a single codebase. Flutter draws its own canvas using graphics engine called Skia. Unlike, React Native, which relies on native components to draw the UI.

“The choice of framework ultimately depends on the requirements and goals of the project. There is no one-size-fits-all solution, and developers must consider the trade-offs and benefits of each option before making a decision and going all in.”

Choose Wisely Meme

It’s very true that many developers focus on making sure their code simply works, but writing high-quality production-level code requires attention to a variety of factors beyond basic functionality. This includes considerations such as scalability, readability, modularity, and adherence to good design patterns.

I have used the MVVM design pattern. I follow a service-oriented architecture, where each view has a view model and view model can call appropriate service method for API calls and to connect to outer world.

Image description

Here is the forgot password view,

import 'package:boiler_plate/ui/common/ui_helpers.dart';
import 'package:boiler_plate/ui/dumb_widgets/circular_progress_indicator.dart';
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked/stacked_annotations.dart';

import 'forgot_view.form.dart';
import 'forgot_viewmodel.dart';

@FormView(
  fields: [
    FormTextField(
      name: 'email',
    ),
  ],
)
class ForgotView extends StackedView<ForgotViewModel> with $ForgotView {
  ForgotView({Key? key}) : super(key: key);

  @override
  Widget builder(
    BuildContext context,
    ForgotViewModel viewModel,
    Widget? child,
  ) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 25.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                  border: Border.all(
                    color: Theme.of(context).colorScheme.onBackground,
                  ),
                ),
                padding: const EdgeInsets.all(16),
                child: const Icon(Icons.fingerprint),
              ),
              verticalSpaceMedium,
              Text(
                'Forgot Password',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
              verticalSpaceMedium,
              Text(
                'No worries, we got you covered.',
                style: Theme.of(context).textTheme.bodyMedium,
              ),
              verticalSpaceMedium,
              TextFormField(
                decoration: const InputDecoration(
                  hintText: 'Email',
                  prefixIcon: Icon(
                    Icons.email,
                  ),
                ),
                enableSuggestions: false,
                autocorrect: false,
                keyboardType: TextInputType.emailAddress,
                textInputAction: TextInputAction.done,
                controller: emailController,
              ),
              verticalSpaceMedium,
              viewModel.isBusy
                  ? const Center(
                      child: MyCircularProgressIndicator(),
                    )
                  : Center(
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          minimumSize: const Size(128, 48),
                        ),
                        onPressed: () {},
                        child: const Text('Reset Password'),
                      ),
                    ),
              verticalSpaceMedium,
              Center(
                child: TextButton(
                  onPressed: viewModel.navigateToLogin,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    mainAxisSize: MainAxisSize.min,
                    children: const [
                      Icon(
                        Icons.arrow_back_ios,
                      ),
                      horizontalSpaceSmall,
                      Text(
                        'Back to Login',
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  ForgotViewModel viewModelBuilder(
    BuildContext context,
  ) =>
      ForgotViewModel();

  @override
  void onViewModelReady(ForgotViewModel viewModel) {
    syncFormWithViewModel(viewModel);
  }

  @override
  void onDispose(ForgotViewModel viewModel) {
    super.onDispose(viewModel);
    disposeForm();
  }
}
Enter fullscreen mode Exit fullscreen mode

and it’s respective forgot view model

import 'package:boiler_plate/app/app.locator.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';

class ForgotViewModel extends FormViewModel {
  final _navigationService = locator<NavigationService>();

  void navigateToLogin() {
    _navigationService.back();
  }
}
Enter fullscreen mode Exit fullscreen mode

Here is the output

Enough Talk. Let’s share some resources for you to have a look at.

Let me introduce Stacked. It provides a simple and elegant state management solution along with its custom without build context navigation, dialog, bottom sheet and snackbar services.
(read detailed documentation here)
Here is the repository to better understand and a very good README waiting for you to start. (Please like 👍 the repo).

We are in the endgame now meme

What’s next? It was all I had to share and it’s time for you guys to do something creative with your next mobile app.
Oh, Also. Don’t forget to hit like 👍 if you find this article useful (It helps me a lot to share valuable info with you) and comment if you have any suggestions.
You can connect with me on LinkedIn or follow me on Medium for more.

Top comments (0)