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
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!
Thanks David for such remarkable words. I have been blogging for 3 months.
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!
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