Start with:
The source code for Flutter first-party plugins (plugins developed by the core Flutter team)
flutter create --org com.example --template=plugin hello
flutter:
plugin:
platforms:
android:
package: com.example.hello
pluginClass: HelloPlugin
ios:
pluginClass: HelloPlugin
macos:
pluginClass: HelloPlugin
web:
pluginClass: HelloPlugin
fileName: hello_web.dart
environment:
sdk: ">=2.1.0 <3.0.0"
flutter: ">=2.10.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
mobx:
flutter_mobx:
provider:
carousel_slider:
cached_network_image:
slide_container:
flutter_swiper:
json_annotation:
auto_orientation:
video_player:
path: ./plugins/packages/video_player
chewie:
path: ./deps/chewie
xml:
dio:
dev_dependencies:
flutter_test:
sdk: flutter
build_runner:
mobx_codegen:
json_serializable:
custom path
1. Mediators created
2. Widgets created
3. Nav. observers / life cycle listeners
4. Routes defined
5. Views set to Mediators
6. Mediators registered in View
1
2
3
4
5
6
public
private
public
private
public
private
Proxies also can sendNotifications
private
Transparent Functional Reactive Programming
Observer (part of the flutter_mobx)
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase with Store {
@observable
int value = 0;
@action
void increment() {
value++;
}
}
To be able to use annotations in your MobX code
@observable, @computed, @action
run this command in terminal:
flutter packages pub run build_runner watch
annotation
ReactionDisposer autorun(Function(Reaction) fn)
ReactionDisposer reaction<T>(T Function(Reaction) predicate, void Function(T) effect)
String greeting = Observable('Mobx World');
final dispose = autorun((_){ print(greeting.value); });
greeting.value = 'Awesome MobX';
dispose(); // Done with the autorun()
// Prints:
// Mobx World
// Awesome MobX
String greeting = Observable('Mobx World');
final dispose = reaction((_) => greeting.value, (msg) => print(msg));
greeting.value = 'Awesome MobX'; // Cause a change
dispose(); // Done with the reaction()
// Prints:
// Awesome MobX
ReactionDisposer when(bool Function(Reaction) predicate, void Function() effect)
String greeting = Observable('Mobx World');
final dispose = when((_) => greeting.value == 'Say', () => print('Awesome MobX'));
greeting.value = 'Say'; // Causes a change, runs effect and disposes
greeting.value = 'MobX'
// Prints:
// Awesome MobX
abstract class _RootStore with Store {
MenuStore menuStore = MenuStore();
HomePageStore homePageStore = HomePageStore();
_RootStore();
...
}
An effective pattern is to create a RootStore that instantiates all stores, and share references. The advantage of this pattern is:
The Observer widget, provides a granular observer of the observables used in its builder function. Whenever these observables change, Observer rebuilds and renders.
special widget for DI/state management, separate from Mobx
Trigger navigation by using the Navigator.pushNamed() method. This tells Flutter to build the widget defined in the routes table and launch the screen.
To navigate back to the first screen, use the Navigator.pop().
The routes define which widget should be created based on the name of the route.
MaterialApp(
routes: {
SomePage.routeName: (context) => SomePage(),
},
);
Function creates the correct route based on the given RouteSettings.
final MethodChannel _channel = const MethodChannel('flutter.io/videoPlayer')
Send messages to Java side through MethodChannel
Register channel with same key
ExoPlayer
@Override
THANK YOU