osam_flutter 3.1.5 osam_flutter: ^3.1.5 copied to clipboard
Navigation and UI elements which fits with Osam library
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:osam_flutter/osam_flutter.dart';
part 'main.g.dart';
final navKey = GlobalKey<NavigatorState>();
final currentContext = navKey.currentState.overlay.context;
const version = 2;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final persist = Persist<AppState, UIState>(appName: 'test');
registerOsamFlutterAdapters();
Hive.registerAdapter(AppStateAdapter());
Hive.registerAdapter(UIStateAdapter());
Hive.registerAdapter(CounterAdapter());
final persistedVersion = await persist.version;
if((persistedVersion ?? -1) < version){
await persist.delete();
}
await persist.init();
final appState = persist.appState ?? AppState();
final uiState = persist.uiState ?? UIState();
runApp(OsamProvider(
appState: appState,
uiState: uiState,
version: version,
child: PersistLifecycleWrapper(
persist: persist,
child: PresenterProvider(
presenter: AppPresenter(),
child: MaterialApp(
navigatorKey: navKey,
home: RootScreen(),
),
),
),
));
}
class RootScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return OsamNavigator<AppPresenter>(
routes: {
appRoutes.first: (ctx) => PresenterProvider(
child: Screen(),
presenter: ScreenPresenter(appRoutes.first),
),
appRoutes.second: (ctx) => PresenterProvider(
child: Screen(),
presenter: ScreenPresenter(appRoutes.second),
),
appRoutes.dialog: () async => showDialog(
context: currentContext,
child: PresenterProvider(
presenter: DialogPresenter(),
child: Builder(
builder: (ctx) {
final presenter = ctx.presenter<DialogPresenter>();
return Material(
child: Column(
children: <Widget>[
Text(presenter.cameFrom),
RaisedButton(
onPressed: () {
presenter.currentRoute.result = 'result from dialog';
},
)
],
),
);
},
),
))
},
);
}
}
class Screen extends StatefulWidget {
@override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> with AfterLayoutMixin {
TextEditingController textEditingController;
@override
void initState() {
textEditingController = TextEditingController();
super.initState();
}
@override
void afterFirstLayout(BuildContext context) {
final presenter = context.presenter<ScreenPresenter>();
textEditingController.addListener(() {
presenter.uiState.login = textEditingController.text;
});
textEditingController.text = presenter.uiState.login;
}
@override
Widget build(BuildContext context) {
final presenter = context.presenter<ScreenPresenter>();
return Scaffold(
appBar: AppBar(
title: Text('Argument is : ${presenter.currentRoute.argument}'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (presenter.route == appRoutes.first)
CupertinoSwitch(
value: presenter.uiState.isSelected,
onChanged: (value) {
setState(() {
presenter.uiState.isSelected = !presenter.uiState.isSelected;
});
},
),
if (presenter.route == appRoutes.first)
TextField(
controller: textEditingController,
),
if (presenter.route == appRoutes.first)
RaisedButton(
child: Text('to other screen'),
onPressed: () => presenter.pushOther(),
),
if (presenter.route == appRoutes.second)
RaisedButton(
child: Text('set result'),
onPressed: () => presenter.setResult(),
),
RaisedButton(
onPressed: presenter.increment,
child: ValueListenableBuilder(
valueListenable: presenter.counterValue,
builder: (_, value, __) => Text(value.toString()),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
presenter.showDialog();
},
),
);
}
}
// presenters
class AppPresenter extends Presenter<UIState, AppState> with NavigationPresenter {
@override
Navigation get navigation => uiState.appNavigation;
}
class ScreenPresenter extends Presenter<UIState, AppState> with NavigationPresenter {
final String route;
ScreenPresenter(this.route);
@override
Navigation get navigation => uiState.appNavigation;
IProperty<int> get counterValue => appState.counter.value;
void increment() => appState.counter.increment();
@override
void init() {
if (route == appRoutes.first)
findRoute(appRoutes.second)?.whenComplete?.then(handleRouteResult);
super.init();
}
void pushOther() =>
push(OsamRoute(appRoutes.second, argument: 'arg from other screen')).then(handleRouteResult);
void handleRouteResult(Object value) {
push(OsamRoute(appRoutes.dialog, argument: value)).then((value) {
print('got result from dialog $value');
});
}
void setResult() {
if (currentRoute.value == appRoutes.second)
setRouteResult(result: 123, route: appRoutes.second);
}
Future<String> showDialog() => push(OsamRoute(appRoutes.dialog, argument: currentRoute.value));
}
class DialogPresenter extends Presenter<UIState, AppState> with NavigationPresenter {
@override
Navigation get navigation => uiState.appNavigation;
String get cameFrom {
return findRoute(appRoutes.dialog).argument.toString();
}
}
@HiveType(typeId: hiveID.appState)
class AppState {
@HiveField(0)
var counter = Counter();
}
@HiveType(typeId: hiveID.counter)
class Counter {
@HiveField(0)
PropertyNotifier<int> _value;
Counter([this._value]) {
_value ??= PropertyNotifier(0);
}
IProperty<int> get value => _value;
void increment() => _value.value++;
}
@HiveType(typeId: hiveID.UIState)
class UIState {
@HiveField(0)
var appNavigation = Navigation(PropertyNotifier([OsamRoute(appRoutes.first)]));
@HiveField(1)
var appTabNavigation = TabNavigation(PropertyNotifier(tabs.first));
@HiveField(2)
var isSelected = false;
@HiveField(3)
var login = '';
}
// ignore: camel_case_types
abstract class appRoutes {
static const first = 'first';
static const second = 'second';
static const dialog = 'dialog';
}
// ignore: camel_case_types
abstract class tabs {
static const first = 'first';
static const second = 'second';
}
// ignore: camel_case_types
abstract class hiveID {
static const appState = 0;
static const counter = 1;
static const UIState = 2;
}