The number of files in the project has grown to a point where it is more difficult to work with. I know because I now need to use ? + P to find files rather than the file explorer.
It now makes sense to start to break up the solution into packages to help make it easier to understand and maintain, and help to ensure each part has a single responsibility.
I started by pulling out the UI widgets as a precursor for creating a storybook to show case them to the stakeholders.
To do this I created a new project called DigestableLego and hosted it on GitLab.
I then moved in the Listview and Listitem widgets, built the package and included it back in DigestableMe Application.
Ta Da
Xp
Creating and using a package
Create package.
flutter create --template=package digestablelego
Create a new Git repository.
git init
git add --all
git commit -m "initial commit"
git remote add origin https://gitlab.com/simbu-mobile/DigestableLego.git
git push -u origin master
Add code and examples to the project.
Check Package is ready to publish.
flutter packages pub publish --dry-run
Once the code passes the checks, check it in.
For now we are going to use it directly from the Git repository e.g.
dependencies:
digestable_lego:
git: https://gitlab.com/simbu-mobile/digestablelego.git
It is likely that in the future I move to a privately hosted pub.dev repository to get the version and update benefits. You can find more details here:
Application Types
We are now up to four:
- MaterialApp
- CupertinoApp
- FluentApp
- MacosApp
They reflect the different design systems/guidelines, Material on Android, Google, Linux and the Web, Cupertino on iOS, Fluent on windows and MacOs on macs.
Currently we are only targeting iOS & Android and extending to the web, so that narrows it down to two:
- MaterialApp
- CupertinoApp
For simplicities sake I’ve now started to move away from device detection and use the application type to differentiate in the widgets that require cross platform support.
import 'package:flutter/cupertino.dart';
extension BuildContextExtension on BuildContext {
bool isCupertinoApp() {
var cupertinoApp = findAncestorWidgetOfExactType<CupertinoApp>();
return cupertinoApp != null;
}
}
// And usage in the cross platform widget
return context.isCupertinoApp()
? const CupertinoListTile()
: const ListTile();
NB: findAncestorWidgetOfExactType is powerful stuff and has a number of uses.
Testing & Development Rhythm
Packaging the UI widgets has given me a moment of clarity with regard to test types.
I would now expect widget and unit tests in the DigestableLego project and feature and unit tests in the DigestableMe project.
Whilst there could possible be the need for widgets tests in DigestableMe it is unlikely, so we shall see how that pans out.
Just looking to build a development rhythm e.g. new UI, build widgets in DigestibleLego and showcase, agree on look and feel and style. Then move to API data side calls and mapping etc… Finally run through the Dev done checklist. More on this later on.
Sound and Vision
Links
- Using packages
- Developing packages & plugins
- Git packages
- Custom package repositories
- How to Create, Publish and Manage Flutter Packages–
- Hosting a private Dart package repository
- A complete guide to Flutter’s ListTile
- 3 Ways to Add Separators between Items in a ListView
- Morphable Shapes
- Raywenderlich.com: Creating and Publishing a Flutter Package