Creative Tips and Tricks for Designing Form Fields, Buttons, Texts, Dialogs, and More

Every design aspect has its good and bad ways to implement it depending on the developer. However, w.r.t Flutter certain widgets are being used daily, but somehow we don’t do it the best we can. So I present to you some Creative Tips and Tricks for Designing Form Fields, Buttons, Texts, Dialog views, and More as we grow with this article. Let’s shed some light.


Table of Contents

– Form Fields

Before we dive into the professional aspect, let’s consider this snippet:

return Column(
      children: [
        
        TextFormField(
          textAlign: TextAlign.center,
          autofocus: true,
          maxLines: 4,
          keyboardType: TextInputType.number,
          textInputAction: TextInputAction.next,
          inputFormatters: [
            LengthLimitingTextInputFormatter(6),
          ],
        ),    
        
        TextFormField(
          textAlign: TextAlign.center,
          autofocus: false,
          keyboardType: TextInputType.emailAddress,
          textInputAction: TextInputAction.next,
          inputFormatters: [],
        ),
        
        .../
      ],
    );

In the above snippet, we need to write the same code again and again and sometimes it becomes hectic too. So here is the professional one.

Create a new dart file as custom_form_field.dart and create a class extending the Widget itself. Consider this snippet:

import 'package:flutter/material.dart';

class CustomFormField extends TextFormField {
  CustomFormField.simple({
    super.key,
    TextEditingController? controller,
    String? hintText,
    ValueChanged<String>? onChanged,
    VoidCallback? onTap,
    bool readOnly = false,
    List<TextInputFormatter>? formatters,
    TextAlign? textAlign,
    TextInputType? inputType,
    TextInputAction? inputAction,
    int? maxLines,
  })  : super(
          controller: controller,
          readOnly: readOnly,
          keyboardType: inputType,
          maxLines: maxLines,
          textInputAction: inputAction,
          decoration: InputDecoration(
            hintText: hintText,
            isDense: true,

          ),
          inputFormatters: formatters,
          textAlign: textAlign ?? TextAlign.start,
          onChanged: onChanged,
          onTap: onTap,
        );
}

Comparatively, this snippet would be easy to utilize, just make use of the named constructor and we’re good at going.

Furthermore, we could also implement a new constructor having borders, since it’s missing in the first one, right?

CustomFormField.rounded({
    super.key,
    TextEditingController? controller,
    String? hintText,
    ValueChanged<String>? onChanged,
    VoidCallback? onTap,
    bool readOnly = false,
    List<TextInputFormatter>? formatters,
    TextAlign? textAlign,
    TextInputType? inputType,
    TextInputAction? inputAction,
    int? maxLines,
  })  : super(
          controller: controller,
          readOnly: readOnly,
          keyboardType: inputType,
          maxLines: maxLines,
          textInputAction: inputAction,
          decoration: InputDecoration(
            hintText: hintText,
            isDense: true,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(20),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(20),
            ),
          ),
          inputFormatters: formatters,
          textAlign: textAlign ?? TextAlign.start,
          onChanged: onChanged,
          onTap: onTap,
        );

It’s that simple. Now let’s use it.

return Column(
      children: [
        
        CustomFormField.simple(
          textAlign: TextAlign.center,
          maxLines: 4,
          inputType: TextInputType.number,
          inputAction: TextInputAction.next,
          formatters: [
            LengthLimitingTextInputFormatter(6),
          ],
        ),

        CustomFormField.rounded(
          textAlign: TextAlign.center,
          maxLines: 4,
          inputType: TextInputType.emailAddress,
          inputAction: TextInputAction.next,
        ),

        .../
      ],
    );

It will perform the same way.

Now let’s look at the next section.

– Buttons

So, up till now, I had an intuition that you had got the current concept. Let’s apply the same approach to buttons as well.

There are two mostly used button types:

Instead of applying styles repeatedly to button widgets, let’s create separate files for Elevated – complete_custom_button.dart, vis-à-vis textButton custom_highlight_button.dart, and extend to their respective Widgets.

complete_custom_button.dart

import 'package:flutter/material.dart';

class CustomCompleteButton extends ElevatedButton {
  CustomCompleteButton({
    required String text,
    required VoidCallback onPressed,
  }) : super(
          child: Text(text),
          onPressed: onPressed,
          style: ElevatedButton.styleFrom(
            alignment: Alignment.center,
            backgroundColor: Colors.amberAccent,
            animationDuration: const Duration(milliseconds: 2000),
            textStyle: const TextStyle(
              fontSize: 13,
              fontWeight: FontWeight.w600,
            ),
            elevation: 0,
            enableFeedback: false,
            padding: const EdgeInsets.all(2),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(14),
            ),
          ),
        );
}

custom_highlight_button.dart

import 'package:flutter/material.dart';

class CustomCompleteButton extends TextButton {
  CustomCompleteButton({
    required String text,
    required VoidCallback onPressed,
  }) : super(
    child: Text(text),
    onPressed: onPressed,
    style: TextButton.styleFrom(
      alignment: Alignment.center,
      backgroundColor: Colors.blueGrey,
      animationDuration: const Duration(milliseconds: 2000),
      textStyle: const TextStyle(
        fontSize: 13,
        fontWeight: FontWeight.w600,
      ),
      elevation: 0,
      enableFeedback: false,
      padding: const EdgeInsets.all(2),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(14),
      ),
    ),
  );
}

Let’s continue to implement texts.

– Texts

Create a new dart file as custom_texts.dart and fill up the following snippet:

class CustomText extends Text {
  CustomText.small({
    required String text,
    TextAlign? textAlign,
    Color? color,
    TextOverflow? overflow,
    FontWeight? fontWeight,
    TextDecoration? textDecoration,
    FontStyle? fontStyle,
  }) : super(
          text,
          overflow: overflow,
          textAlign: textAlign ?? TextAlign.center,
          style: Theme.initialize.textTheme.displaySmall!.copyWith(
            color: color,
            fontWeight: fontWeight ?? FontWeight.normal,
            decoration: textDecoration,
            fontStyle: fontStyle,
          ),
        );

  CustomText.medium({
    required String text,
    TextAlign? textAlign,
    Color? color,
    TextOverflow? overflow,
    FontWeight? fontWeight,
    double? fontSize,
    TextDecoration? textDecoration,
    FontStyle? fontStyle,
    double? letterSpacing,
  }) : super(
          text,
          overflow: overflow,
          textAlign: textAlign ?? TextAlign.center,
          style: Theme.initialize.textTheme.displayMedium!.copyWith(
            color: color,
            fontWeight: fontWeight ?? FontWeight.normal,
            fontSize: fontSize,
            decoration: textDecoration,
            fontStyle: fontStyle,
            letterSpacing: letterSpacing,
          ),
        );

  CustomText.large({
    required String text,
    TextAlign? textAlign,
    Color? color,
    TextOverflow? overflow,
    FontWeight? fontWeight,
    double? fontSize,
  }) : super(
          text,
          overflow: overflow,
          textAlign: textAlign ?? TextAlign.center,
          style: Theme.initialize.textTheme.displayLarge!.copyWith(
            color: color,
            fontWeight: fontWeight ?? FontWeight.normal,
            fontSize: fontSize,
          ),
        );
}

With this approach, our workload has been reduced to quite a deep extent. We don’t need to repeatedly define styles, font size, and so on…

Usage

Expanded(
   child: ListView(
       shrinkWrap: true,
       children: [
           CustomText.large(text: 'PROJECT NAME', textAlign: TextAlign.left, overflow:   TextOverflow.fade,),

           Divider(
              color: Colors.grey[400]!,
              thickness: 7,
           ),

          CustomText.medium(text: 'SUPERVISOR', textAlign: TextAlign.left, fontSize: 12.sp,),
          CustomText.small(text: 'Participants\n\nABC', textAlign: TextAlign.left),
        ],
      ),
    ),

Let’s move to the next section.

– Dialogs

For the sake of simplicity, we shall be taking only AlertDialog into account because the rest of the work is the same.

Create a new file as custom_alert_dialog.dart and jot down this code snippet:

import 'package:flutter/material.dart';

class CustomAlertDialog extends AlertDialog {
CustomAlertDialog({
String? title,
List<Widget>? actions,
Widget? content,
}) : super(
title: Text(title!),
titlePadding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
alignment: Alignment.center,
elevation: 3,
actions: actions ?? [],
content: content,
);
}

Let’s move to the final phase of this article, and it’s going to be fascinating to implement.

– Flutter Extensions

Extensions add functionality to existing libraries. As introduced in Dart 2.7 and onwards, we can add our methods under a variety of types, but about our specific project.

The interesting aspect of this is, that we unknowingly use these in our daily developments. Such as,

'dummy-string'.trim();
 int.parse('33');

 some-value.toString();

Let’s look at the extension mockup:

extension ExtensionTitle on type {
  type get methodName => functionality;
}

Let’s take an example.

Consider I need to show the current DateTime in the format yMd(). (don’t forget to add intl plugin)

extension FormatDateExtension on DateTime {
 String get formatter => DateFormat.yMd().format(this);
}

Here, this represents the current DateTime instance.

How to use this?

Old approach
Text(
 DateFormat.yMd().format(DateTime.now().toString()),
 style: TextStyle(
  fontSize: 44,
  fontWeight: FontWeight.bold,
 ),
),
Extension view
Text(
 DateTime.now().formatter,
 style: TextStyle(
  fontSize: 44,
  fontWeight: FontWeight.bold,
 ),
),

Let’s now look at a tricky one,

Get the full height and width via Media Query. But before that, let’s look at the old way of doing it.

Incorrect approach
Container(
 height: MediaQuery.of(context).size.height,
 width: MediaQuery.of(context).size.width,
 child: DummyChildWidget(),
),
Extension View with the Correct Approach
extension BuildContextExtension on BuildContext {
 double get fullWidth => MediaQuery.of(this).size.width;
 double get fullHeight => MediaQuery.of(this).size.height;
}

Container(
 height: context.fullHeight,
 width: context.fullWidth,
 child: DummyChildWidget(),
),

It’s that simple. Both will give us the same output, but this one reduces a lot of boilerplate code.

It’s time to wrap up this article. That’s all!


Wrapping Up

Thanks for your precious time.

Hope you enjoyed every bit of it.

So, in this blog, we got to know about Creative Tips and Tricks for Designing Form Fields, Buttons, Texts, Dialogs, and More. Apart from that, we had some useful code snippets and certain examples.

If you think I missed out on something or want to add your point of view, please jot it down in the comments section below. I would love to know that as well.

Link to GitHub Repositories, and YouTube Channel

Also, read Flutter’s Best Practices for High-Performing and User-Friendly Apps for 2023

Read out previous blogs – Click here

4 thoughts on “Creative Tips and Tricks for Designing Form Fields, Buttons, Texts, Dialogs, and More”

  1. Wow, wonderful weblog structure! How lengthy have you
    been blogging for? you made blogging look easy. The total glance of your website is excellent, let alone the content!

    Reply
  2. Good day! Do you know if they make any plugins to assist with Search Engine Optimization? I’m
    trying to get my blog to rank for some targeted keywords but I’m not seeing
    very good success. If you know of any please share. Many thanks!

    Reply
    • Hey James, well I don’t know about any sort of plugins, but I would say that; focus more on the content itself, your blog shall rank automatically, give it some time. Regards, Mustafa

      Reply

Leave a Comment