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.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

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.

Completed Classical app

Here is what it looks like in action:

Audio widget with music

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 with pub 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 a CustomPainter 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.

Jonathan Sande

Contributors

Jonathan Sande

Author

Ben Wicks

Author and Tech Editor

Adriana Kutenko

Illustrator

Aldo Olivares

Final Pass Editor

Brian Kayfitz

Team Lead

Over 300 content creators. Join our team.