arch 0.2.0+1 copy "arch: ^0.2.0+1" to clipboard
arch: ^0.2.0+1 copied to clipboard

discontinued

MVVM architecture components for Flutter. Helps developers build loosely-coupled applications.

example/lib/main.dart

import 'package:arch/arch.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp(AppInitializer()));

class AppInitializer implements Initializer {
  @override
  void registerTypes(ServiceRegistry registry) {
    registry
      ..registerLazySingleton<Logger>(() => DebugLogger())
      ..registerView(
        view: () => HomeView(),
        viewModel: () => HomeViewModel(registry.resolve<NavigationService>()),
        viewName: 'HomeView',
      )
      ..registerView(
        view: () => SecondView(),
        viewModel: () => SecondViewModel(
          registry.resolve<NavigationService>(), // NavigationService and DialogService are automatically registered
          registry.resolve<DialogService>(),
          registry.resolve<Logger>(),
        ),
        // This will default to the view's type name `SecondView`.
      )
      ..registerDialog(
        dialog: () => MyCustomDialog(),
        dialogModel: () => MyCustomDialogModel(registry.resolve<DialogService>()),
        // This will default to the dialog's type name `MyCustomDialog`.
      );
  }
}

/// Log provider.
abstract class Logger {
  /// Logs a message
  void log(String message);
}

/// Debug log provider.
class DebugLogger implements Logger {
  @override
  void log(String message) => print(message);
}

class ParameterNames {
  static const messageFromHome = 'messageFromHome';
  static const messageFromSecond = 'messageFromSecond';
  static const messageForDialog = 'messageForDialog';
  static const messageFromDialog = 'messageFromDialog';
}

class MyApp extends Application {
  MyApp(Initializer initializer) : super(initializer);

  @override
  void onInitialize() {
    print('Initialized');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Arch Demo',
      navigatorKey: NavigationService.navigatorKey, // IMPORTANT
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomeView(),
    );
  }
}

class HomeView extends StatefulWidget {
  HomeView() : super(key: Key('HomeView'));

  @override
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends ViewStateBase<HomeView, HomeViewModel> {
  @override
  Widget buildView(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(viewModel.title)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times: ${viewModel.counter}'),
            RaisedButton(
              child: Text('Go to Second View'),
              onPressed: viewModel.navigate,
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => viewModel.counter++,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class HomeViewModel extends ViewModelBase {
  HomeViewModel(NavigationService navigationService) : super(navigationService: navigationService);

  final title = 'Home View';

  int _counter = 0;
  int get counter => _counter;
  set counter(int value) {
    if (_counter != value) {
      _counter = value;
      notifyListeners('counter');
    }
  }

  Future<void> navigate() async {
    final result = await navigationService.push('SecondView', {ParameterNames.messageFromHome: 'Hello'});
    if (result?.containsKey(ParameterNames.messageFromSecond) == true) {
      print(result[ParameterNames.messageFromSecond]);
    }
  }
}

class SecondView extends ViewBase<SecondViewModel> {
  SecondView() : super(key: Key('SecondView'));

  @override
  Widget buildView(BuildContext context, SecondViewModel viewModel) {
    return Scaffold(
      appBar: AppBar(title: Text(viewModel.title)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              child: Text('Go Back'),
              onPressed: viewModel.goBack,
            ),
            RaisedButton(
              child: Text('Show Alert Dialog'),
              onPressed: viewModel.showAlertDialog,
            ),
            RaisedButton(
              child: Text('Show Custom Dialog'),
              onPressed: viewModel.showCustomDialog,
            ),
          ],
        ),
      ), //
    );
  }
}

class SecondViewModel extends ViewModelBase {
  SecondViewModel(NavigationService navigationService, DialogService dialogService, this._logger)
      : super(navigationService: navigationService, dialogService: dialogService);

  final Logger _logger;

  final title = 'Second View';

  @override
  void init([Map<String, Object> parameters]) {
    if (parameters?.containsKey(ParameterNames.messageFromHome) == true) {
      _logger.log(parameters[ParameterNames.messageFromHome]);
    }
  }

  void goBack() => navigationService.pop({ParameterNames.messageFromSecond: 'Hi!'});

  void showAlertDialog() => dialogService.alert('This is an alert dialog');

  Future<void> showCustomDialog() async {
    final result =
        await dialogService.showCustomDialog('MyCustomDialog', {ParameterNames.messageForDialog: 'Edit this'});

    if (result?.containsKey(ParameterNames.messageFromDialog) == true) {
      print('Edited value: ${result[ParameterNames.messageFromDialog]}');
    }
  }
}

class MyCustomDialog extends DialogBase<MyCustomDialogModel> {
  final _controller = TextEditingController();

  @override
  void didInitDialogModel(MyCustomDialogModel dialogModel) {
    _controller.text = dialogModel.originalInput;
  }

  @override
  Widget buildDialog(BuildContext context, MyCustomDialogModel dialogModel) {
    return AlertDialog(
      title: Text('Enter an input'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text('This is an alert dialog that takes an input.'),
          SizedBox(height: 8),
          TextField(controller: _controller)
        ],
      ),
      actions: <Widget>[
        FlatButton(
          child: Text('Cancel'),
          onPressed: () => dialogModel.pop(),
        ),
        FlatButton(
          child: Text('Ok'),
          onPressed: () => dialogModel.pop({ParameterNames.messageFromDialog: _controller.text}),
        ),
      ],
    );
  }
}

class MyCustomDialogModel extends DialogModelBase {
  MyCustomDialogModel(DialogService dialogService) : super(dialogService);

  String originalInput;

  @override
  void init([Map<String, Object> parameters]) {
    if (parameters?.containsKey(ParameterNames.messageForDialog) == true) {
      originalInput = parameters[ParameterNames.messageForDialog];
    }
  }
}
2
likes
30
pub points
0%
popularity

Publisher

unverified uploader

MVVM architecture components for Flutter. Helps developers build loosely-coupled applications.

Homepage
Repository
View/report issues

License

MIT (LICENSE)

Dependencies

flutter, get_it, meta, page_transition, provider

More

Packages that depend on arch