Creating Reusable Custom Widgets in Flutter
Learn how to design and create your own custom widgets in Flutter that you can use in any of your projects or share with the world. By Jonathan Sande.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Creating Reusable Custom Widgets in Flutter
25 mins
- Getting Started
- Refactoring UI Layouts
- Extracting Widgets
- Types of Custom Widgets
- Designing Your Widget
- Decomposing the Design
- Building the Basic Widget
- Customizing the Look
- Determining the User Interaction
- Defining the Parameters
- Implementing the Parameters
- Converting to StatefulWidget
- Adding a StatefulWidget Constructor
- Implementing the Play Button
- Implementing the Seek Bar
- Implementing the Current Time Label
- Implementing the Total Time Label
- Testing the Widget
- Sharing Your Widget With the World
- Where to Go From Here?
Testing the Widget
Widget testing is an important part of creating custom widgets. To keep this article a manageable size, it won’t cover widget testing, but you should read An Introduction to Widget Testing in the Flutter documentation and Widget Testing With Flutter: Getting Started here on raywenderlich.com.
For now, you’ll just test that AudioWidget
works by hooking it up to an audio plugin. The view model in the starter project is all ready to communicate with your new widget.
In lib/main.dart, delete the entire AudioPlayer class, located at the bottom of the file, then add the following code:
class AudioPlayer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelBuilder<AudioViewModel>.reactive(
viewModelBuilder: () => AudioViewModel(),
onModelReady: (model) => model.loadData(),
builder: (context, model, child) => AudioWidget(
isPlaying: model.isPlaying,
onPlayStateChanged: (bool isPlaying) {
model.onPlayStateChanged(isPlaying);
},
currentTime: model.currentTime,
onSeekBarMoved: (Duration newCurrentTime) {
model.seek(newCurrentTime);
},
totalTime: model.totalTime,
),
);
}
}
AudioWidget
is the most important part here. It gets its state from model
and rebuilds whenever the values there change. It also updates model
when the user presses the Play/Pause button or moves the seek bar.
Do a hot reload, press the Play button and enjoy the concert.
Here is what it looks like in action:
Sharing Your Widget With the World
Now that you have a working version of AudioWidget
, you or anyone else can use it simply by copying audio_widget.dart into a project. You can make it even easier for other people to use it by sharing it on Pub, the central repository for Flutter and Dart packages.
Here are a few general guidelines for adding a Pub package:
- Start a new Flutter project in Android Studio and choose Flutter Package for the project type.
- Put your custom widget in the lib folder.
- Add a folder named example to the project root. In there, add a Flutter app that demonstrates how to use your widget. The example project’s pubspect.yaml imports the widget using
path: ../
. Find other developers’ examples on GitHub to see how they did it. Most Pub packages have links to their GitHub repos. - Make a GitHub repository for your own project. Make sure all your public methods and parameters have comment documentation.
- Read Developing Packages & Plugins and Publishing Packages.
- Once you’ve set everything up, running
pub publish
from the project root is how you publish your package. First, however, you should test it withpub publish --dry-run
.
Where to Go From Here?
Download the final project using the Download Materials button at the top or bottom of this tutorial.
If you want to improve the widget, here are a few ideas:
- Add more constructor parameters to allow developers to further customize how the widget looks and behaves.
- Support playing audio from remote sources by allowing the Play button to show a circular progress indicator while the audio file is downloading or buffering.
- Replace
Slider
with aCustomPainter
where you draw the play progress and buffered content separately. Refer to RangeSlider for ideas.
Here are a couple good videos to learn more about building custom widgets:
If you have any comments or questions, please leave them in the forum discussion below.