Introduction
While coding using Flutter you must have wrote that code to get the screen’s height MediaQuery.of(context).size.height
if you have wished it could be shorter like context.height
or you have used a package that offers such code then this article about extension methods
is for you.
Why extension methods?
Extension methods
were added to Dart 2.7 so you can add methods
or properties
to classes that you don’t own the code for be it in Dart, Flutter or a third-part package.
Before extensions
we had to use helper methods to have the same functionality, if we want to get the height from context we would write a function like this.
getScreenHeight(context) {}
The same goes for getting the space separated word count of a string
getWordsCount(string) {}
The syntax
It’s a lot easier writing extension methods
all you get to write is extension ExtensionName on ClassName {}
and you will get access to the class instance using this
keyword
Example:
|
|
Overview of our app
The app we are going to learn extension methods
with can be found on Github so you can clone or download it and try it out.
It’s a fairly simple app that has a TextField
with certain maxLines
extracted into a varialbe of the same name, it is wrapped inside a Column
that is inside a SizedBox
with height
equal to screen’s height, below the TextField
is a Text
that shows how many space separated words are in the TextField
Note : Some code is replaced with ...
for brevity.
|
|
In the helpers.dart
file we have three helper functions that use Classes
we can’t change their source code like BuildContext
, String
and num
, and we will change those functions into extension methods
.
|
|
Converting to extension methods
We will add our exxtension methods
into extensions.dart
file and helpers.dart
file will be right next to it to view changes done.
-
We will first apply extension on
BuildContext
using the aforementioned syntaxExtension ContextExtensions on BuildContext
and import it from thewidget.dart
file in Flutter .. Then we will add a getter that returnsdouble
where it returns theMediaQuery
’sSize
’sheight
so we can use it in our code ascontext.height
.
1 2 3 4 5
import 'package:flutter/widgets.dart'; ... extension ContextExtensions on BuildContext{ double get height => MediaQuery.of(this).size.height; }
1 2 3 4 5
import 'package:flutter/widgets.dart'; ... double getScreenHeight(BuildContext context) { return MediaQuery.of(context).size.height; }
-
As for the
getWordsCount
we will also use the same syntax, it can be either amethod
orproperty
with a getter but I feel like a getter here would be more fitting.
|
|
|
|
- Finally for the
addTen
extension
onnum
, here it is obvious that it should be a method but the issue here is related toinheritance
since bothdouble
andint
inherit fromnum
we can run into runtime errors as the compiler won’t complain.
type 'double' is not a subtype of type 'int'
as we will be passing adouble
value to anint
variable if we useint maxLines = 5.0.addTen()
.
ButGenerics
come to the rescue in such situation, we will refactor our code to return a generic type thatextends
num
and now our compiler will tell us there is an issue with such assignment.
|
|
|
|
Note
We could have definitely made the method or extension return an
int
but this is only an example to see how to apple one code to two classes that have the same parent without repeating our code using generics generics
And after applying our extension methods code main.dart
will look like this:
|
|
Wrapping up and important notes
Our app was simple so this article can be as short as it can be, but it showed us how using extensions
can make our code shorter, cleaner and more concise in place of helper methods.
We shouldn’t make an extension for every simple use case though lest we change the simple interface that Flutter is famous for, but it can be helpful for repetitive code like String
validation for example or getting screen size from MediaQuery
for responsiveness.
Some important notes about extension methods
:
- Our variables have to be the same type that our
extension
is on, if they are dynamic it will throw aruntime error
.
i.e:String
extensions have to be called onString
variables.
|
|
|
|
- We can use
extensions
onoperators
as well such as-
and&
not only properties and methods, as such:
|
|
- We can’t
override
the originalclass
’s properties and methods,extension methods
is not the same as inheritance, it is only used to add functionality.
|
|
- If we have mutiple
extensions
with the same name we can eitherhide
the one we don’t need or use extensions likeWrapper class
if we need to use both of them in the same file.
|
|
|
|
I hope this article was insightful and taught you the power and limitations of
Dart extension methods
in Flutter.Feel free to share the article if you want, leave feedback in the comments or through contacting me, ask me anything or suggest a topic for another article.
Thanks!