arrow-left arrow-right brightness-2 chevron-left chevron-right facebook-box facebook loader magnify menu-down rss-box star twitter-box twitter white-balance-sunny window-close
How to Create a Flutter Library: my_changelog
4 min read

How to Create a Flutter Library: my_changelog

How to Create a Flutter Library: my_changelog

Flutter and the Dart ecosystem makes it easy to create, publish and use new libraries. Within our Flutter applications we can pull libraries in from the filesystem, Git, and pub.dev, making it easy to make new changes during the development/distribution phase.

What will we be making?

You've been tasked with a way to display a CHANGELOG inside of your application. You decide to create a library for this to make it reusable and offer powerful (future) features such as dialog popups, auto-show on version number change, and so on.

Prior to working on the more complex features, you decide to get an early MVP up and running - simply displaying a CHANGELOG.md file from a local asset or parsing Markdown from a String.

Creating a Flutter project

As always, we can go ahead and create a new Flutter project prior to creating our library:

$ flutter create my_app
Run this inside of your terminal! :)

This will serve as a test bed as we'll be loading our library from the filesystem during development. We'll come back to this later on in the tutorial!

Creating a Flutter library

Next up, we can create a new library by opening a new terminal window and typing the following:

$ flutter create --template=package my_changelog

This will create a new library project named my_changelog. Let's open it up inside of our editor:

$ cd my_changelog
$ code .

We should now be able to see the stock Calculator class and the surrounding test file at lib/my_changelog.dart and test/my_changelog_test.dart:

library my_changelog;

/// A Calculator.
class Calculator {
  /// Returns [value] plus 1.
  int addOne(int value) => value + 1;
}

There's also other key files that'll need to be configured prior to our deployment such as LICENSE and CHANGELOG.md, aside from that, it's a completely bare-bones Dart/Flutter project.

Adding our dependencies

Let's head over to pubspec.yaml and under the dependencies: key, add the flutter_markdown plugin. We'll need this to parse the Markdown content that we'll be passing into our library later on.

NOTE: We don't need to add the Flutter dependency because we generated this with the Flutter SDK
dependencies:
  flutter:
    sdk: flutter
  flutter_markdown: ^0.3.3

Once you've done this, save the file. If your environment doesn't run flutter pub get by default, run this inside of your terminal from within the my_changelog directory.

Creating the ChangeLogScreen

Next up, we'll be making the ChangeLogScreen that we can import inside of our my_app project that we created earlier. Add the following to your lib/my_changelog.dart file:

library my_changelog;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

class ChangeLogScreen extends StatelessWidget {
  final Widget title;
  final String markdownData;
  final bool showAppBar;
  final String markdownFilePath;

  final ScrollController scrollController = ScrollController();

  ChangeLogScreen({
    this.title,
    this.markdownData,
    this.showAppBar = true,
    this.markdownFilePath,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: showAppBar
          ? AppBar(
              title: title ?? Text(""),
              leading: IconButton(
                icon: Icon(Icons.close),
                onPressed: () => Navigator.of(context).pop(),
              ),
            )
          : null,
      body: SafeArea(
        child: markdownFilePath != null
            ? FutureBuilder(
                future: rootBundle.loadString(markdownFilePath),
                builder:
                    (BuildContext context, AsyncSnapshot<String> snapshot) {
                  if (snapshot.hasData) {
                    return Markdown(
                      controller: scrollController,
                      data: snapshot.data,
                    );
                  }

                  return Center(child: CircularProgressIndicator());
                },
              )
            : Markdown(
                controller: scrollController,
                data: markdownData,
              ),
      ),
    );
  }
}

This should hopefully meet our MVP requirement. We're able to currently customise a StatelessWidget which contains a Scaffold that optionally has an AppBar, markdown support for rootBundle (i.e. project assets), text, and so on.

Adding the my_changelog dependency

Now that we have the foundation of our my_changelog library, we can go ahead and view this inside of our my_app project.  Open this up inside of your editor and head on over to pubspec.yaml and edit your dependencies to include the path for my_changelog on your machine:

dependencies:
  flutter:
    sdk: flutter
  my_changelog:
    path: "../my_changelog"
Once again, you'll need to run flutter pub get if your environment does not automatically fetch packages after changing this file.

We can also use git instead of a local path here:

my_changelog:
    git:
      url: git://github.com/username/repo.git

Using our library

Now that we've got the my_changelog library, we'll be able to use the exported ChangeLogScreen inside of my_app. Head over to lib/main.dart and update your build to use this:

import 'package:flutter/material.dart';
import 'package:my_changelog/my_changelog.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ChangeLogScreen(
          title: Text("Changelog"),
          markdownData: """
## 1.1 - 22/02/2020
- Fixed an issue where the lorem wouldn't ipsum.
- Stability improvements.
- Security and bug fixes.

## 1.0 - 21/02/2020
- Added a changelog to the application.
          """,
        ));
  }
}

We can now start our project using the debugger on either an iOS or Android emulator/device, showing our ChangeLogScreen in action:

Changelog in action!

We could also display this data using the markdownFilePath if we wanted to turn this into it's own file (such as assets/CHANGELOG.md).

Conclusion

In this article we created a new Flutter library to accommodate a CHANGELOG or other Markdown data. In the next part of our library series, we'll look at how to publish this on pub.dev and make this accessible to everyone without needing it locally or using the git URL.