Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

HTD-Health/flutter_starter_app

Repository files navigation

flutter_starter_app

1. Basic Commands

  • flutter analyze - linting
  • flutter run - start app
  • flutter format . - format all files in current directory
  • flutter pub global run devtools (or devtools) - open dev tools
  • flutter packages pub run build_runner build --delete-conflicting-outputs - run build_runner to generate *.g.dart files (replace build with watch to build files in watch mode)
  • flutter drive --target=test_driver/app.dart - run e2e tests with flutter driver (optionally add --no-build flag to not rebuild source code if only tests changed)

2. How to BloC with Provider

2.1. Create BloC class

class ExampleBloc extends ChangeNotifier {
  List<String> _texts = [];
  List<String> get texts => _texts;

  void addText(String text) {
    _texts.add(text);
    notifyListeners();
  }

  void clear() {
    _texts.clear();
    notifyListeners();
  }
}
  • It's important to call notifyListeners method after every action. This will notify every listeners that listens to our ChangeNotifier object which extends our BloC class.

2.2. Provide BloC object down the tree:

ChangeNotifierProvider<ExampleBloc>(
  child: MaterialApp(
    title: 'MyTitle',
    home: HomeScreen(),
  ),
  // Here we are creating our BloC object
  create: (BuildContext context) => ExampleBloc(),
);

2.3. Get access to BloC object from widgets placed down the tree

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    ExampleBloc bloc = Provider.of<ExampleBloc>(context);
    return Container(
      // implementation...
    );
  }
}

To reload only specific part of tree use Consumer widget instead of Provider.of

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Consumer<ExampleBloc>(
      // Only widgets returned from this builder method
      // will be updated when bloc objects will be modified
      builder: (
        BuildContext context,
        ExampleBloc value,
        Widget child,
      ) {
        return Container(child: child);
      },
      // This part of tree will remain unchanged
      child: Container(),
    );
  }
}

You can also use Selector widget to ignore changes if they don't have an impact on the widget tree.

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    // <(BloC Type), (The type of value we are looking for changes)>
    return Selector<ExampleBloc, int>(
      child: Container(),
      // value argument is our value returned from selector method 
      builder: (BuildContext context, int value, Widget child) {
        return Container();
      },
      // The constructor method will be called whenever the value
      // returned from the selection method is changed
      selector: (BuildContext context, ExampleBloc bloc) => bloc.texts.length,
    );
  }
}

2.4. That's all. Use methods on on your BloC objects and all will be updated!

3. Project analysis options

4. Json serialization

4.1. To create JSON serialize create model file like:

import 'package:json_annotation/json_annotation.dart';

/// You need to add `part` file import in way descripted below:
/// ```
/// part '<your_file_name>.g.dart'
/// ```
///
/// It's like importing your file current file but with `.g` before
/// your `.dart` extension.
part 'example_photo_model.g.dart';

/// Json serialization config
/// more about: 
/// `https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html`
@JsonSerializable(nullable: false, checked: true)
class ExamplePhotoModel {
  final String id;
  final String author;
  final int width;
  final int height;
  final String url;
  /// Map from json `download_url` field to property `downloadUrl`
  @JsonKey(name: 'download_url')
  final String downloadUrl;

  ExamplePhotoModel({this.id, this.author, this.width, this.height, this.url});

  /// Just simply copy paste the following lines to your model
  /// and replace `ExamplePhotoModel` with your model class
  factory ExamplePhotoModel.fromJson(Map<String, dynamic> json) =>
      _$ExamplePhotoModelFromJson(json);
  Map<String, dynamic> toJson() => _$ExamplePhotoModelToJson(this);
}

4.2. Run flutter pub run build_runner build

4.3. Thats all. To parse json:

ExamplePhotoModel photo = ExamplePhotoModel.fromJson(decodedJson);

5. Api

This starter app uses a simple wrapper around dart http client library that adds the possibility to handle middlewares by ApiLinks (strongly inspired by apollo graphQL client links) [MORE].

6. Firebase integration

  1. Create your firebase app CLICK HERE
  2. Configure project CLICK HERE
  3. Add google-service.json and GoogleService-Info.plist files to your project.
  • It is important to have the same app identifiers for both, firebase and flutter app: com.example.myapp

6.1 Firebase performance example

You can measure your app performance in specific

final Trace myTrace = FirebasePerformance.instance.newTrace("test_trace");
myTrace.start();

final Item item = cache.fetch("item");
if (item != null) {
  myTrace.incrementMetric("item_cache_hit", 1);
} else {
  myTrace.incrementMetric("item_cache_miss", 1);
}

myTrace.stop();

About

Starter application for flutter based projects

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published