- flutter_starter_app
flutter analyze
- lintingflutter run
- start appflutter format .
- format all files in current directoryflutter pub global run devtools
(ordevtools
) - open dev toolsflutter packages pub run build_runner build --delete-conflicting-outputs
- run build_runner to generate*.g.dart
files (replacebuild
withwatch
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)
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 ourChangeNotifier
object which extends our BloC class.
ChangeNotifierProvider<ExampleBloc>(
child: MaterialApp(
title: 'MyTitle',
home: HomeScreen(),
),
// Here we are creating our BloC object
create: (BuildContext context) => ExampleBloc(),
);
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,
);
}
}
- camel_case_types
- library_names
- file_names
- library_prefixes
- non_constant_identifier_names
- lines_longer_than_80_chars
- slash_for_doc_comments
- prefer_adjacent_string_concatenation
- prefer_interpolation_to_compose_strings
- prefer_function_declarations_over_variables
- unnecessary_lambdas
- prefer_equal_for_default_values
- avoid_init_to_null
- unnecessary_getters_setters
- prefer_initializing_formals
- type_init_formals
- empty_constructor_bodies
- unnecessary_new
- use_rethrow_when_possible
- use_to_and_as_if_applicable
- prefer_final_fields
- use_setters_to_change_properties
- avoid_returning_this
- avoid_positional_boolean_parameters
- hash_and_equals
- avoid_null_checks_in_equality_operators
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_statements
- prefer_single_quotes
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);
}
ExamplePhotoModel photo = ExamplePhotoModel.fromJson(decodedJson);
This starter app uses a simple wrapper around dart http
client library that adds the
possibility to handle middlewares by ApiLink
s (strongly inspired by apollo graphQL
client links) [MORE].
- Create your firebase app CLICK HERE
- Configure project CLICK HERE
- Add
google-service.json
andGoogleService-Info.plist
files to your project.
- It is important to have the same app identifiers for both, firebase and flutter app:
com.example.myapp
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();