Convert Figma logo to code with AI

brianegan logoflutter_architecture_samples

TodoMVC for Flutter

8,738
1,711
8,738
46

Top Related Projects

The repo contains the source code for all the tutorials on the FilledStacks Youtube channel.

[Example APPS] Basic Flutter apps, for flutter devs.

An awesome list that curates the best Flutter libraries, tools, tutorials, articles and more.

17,049

A collection of Flutter examples and demos

11,778

A predictable state management library that helps implement the BLoC design pattern

Quick Overview

The brianegan/flutter_architecture_samples repository is a collection of sample apps that demonstrate different architectural approaches to building Flutter applications. It showcases various state management techniques and design patterns, providing developers with practical examples of how to structure their Flutter projects.

Pros

  • Offers multiple implementations of the same app using different architectures, allowing for easy comparison
  • Provides real-world examples of popular state management solutions in Flutter
  • Includes detailed explanations and documentation for each architecture
  • Regularly updated to reflect current best practices and new Flutter features

Cons

  • May be overwhelming for beginners due to the variety of architectures presented
  • Some implementations might become outdated as Flutter and its ecosystem evolve
  • Focuses primarily on a single app example, which may not cover all use cases
  • Limited coverage of newer state management solutions

Code Examples

Here are a few code examples from different architectural approaches:

  1. BLoC Pattern (Business Logic Component):
class TodosBloc extends Bloc<TodosEvent, TodosState> {
  TodosBloc() : super(TodosLoading()) {
    on<LoadTodos>(_onLoadTodos);
    on<AddTodo>(_onAddTodo);
    on<UpdateTodo>(_onUpdateTodo);
    on<DeleteTodo>(_onDeleteTodo);
  }

  void _onLoadTodos(LoadTodos event, Emitter<TodosState> emit) async {
    try {
      final todos = await _todosRepository.loadTodos();
      emit(TodosLoaded(todos));
    } catch (_) {
      emit(TodosNotLoaded());
    }
  }

  // Other event handlers...
}
  1. Redux:
class AppState {
  final List<Todo> todos;
  final VisibilityFilter activeFilter;

  AppState({required this.todos, required this.activeFilter});

  AppState copyWith({List<Todo>? todos, VisibilityFilter? activeFilter}) {
    return AppState(
      todos: todos ?? this.todos,
      activeFilter: activeFilter ?? this.activeFilter,
    );
  }
}

AppState appReducer(AppState state, dynamic action) {
  return AppState(
    todos: todosReducer(state.todos, action),
    activeFilter: visibilityFilterReducer(state.activeFilter, action),
  );
}
  1. Provider:
class TodosModel extends ChangeNotifier {
  List<Todo> _todos = [];

  List<Todo> get todos => _todos;

  void addTodo(Todo todo) {
    _todos.add(todo);
    notifyListeners();
  }

  void toggleTodo(Todo todo) {
    final index = _todos.indexOf(todo);
    _todos[index] = todo.copyWith(complete: !todo.complete);
    notifyListeners();
  }

  // Other methods...
}

Getting Started

To get started with the Flutter Architecture Samples:

  1. Clone the repository:

    git clone https://github.com/brianegan/flutter_architecture_samples.git
    
  2. Navigate to a specific example directory:

    cd flutter_architecture_samples/example_name
    
  3. Run the app:

    flutter run
    

Explore different architectures by repeating steps 2-3 for various example directories.

Competitor Comparisons

The repo contains the source code for all the tutorials on the FilledStacks Youtube channel.

Pros of flutter-tutorials

  • More comprehensive, covering a wide range of Flutter topics and concepts
  • Regularly updated with new tutorials and examples
  • Includes video tutorials alongside code samples for better learning experience

Cons of flutter-tutorials

  • Less focused on specific architecture patterns
  • May be overwhelming for beginners due to the large number of tutorials
  • Lacks a unified example app to demonstrate concepts cohesively

Code Comparison

flutter-tutorials:

class HomeViewModel extends BaseViewModel {
  final _api = locator<Api>();
  List<Post> posts;

  Future fetchPosts() async {
    setBusy(true);
    posts = await _api.getPosts();
    setBusy(false);
  }
}

flutter_architecture_samples:

class TodosBloc extends Bloc<TodosEvent, TodosState> {
  TodosBloc({@required this.todosRepository})
      : assert(todosRepository != null),
        super(TodosLoading());

  final TodosRepository todosRepository;
}

The flutter-tutorials example showcases a ViewModel approach using a BaseViewModel, while flutter_architecture_samples demonstrates a BLoC pattern implementation. The former focuses on simplicity, while the latter emphasizes separation of concerns and state management.

[Example APPS] Basic Flutter apps, for flutter devs.

Pros of FlutterExampleApps

  • Wider variety of examples covering different Flutter features and use cases
  • More beginner-friendly with simpler, standalone examples
  • Regularly updated with new examples and Flutter features

Cons of FlutterExampleApps

  • Less focus on architectural patterns and best practices
  • Examples may not always follow consistent coding standards
  • Some examples might be too simplistic for advanced developers

Code Comparison

FlutterExampleApps (Simple Counter App):

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
}

flutter_architecture_samples (Counter App with Redux):

class CounterViewModel {
  final int count;
  final Function() onIncrement;
  CounterViewModel({required this.count, required this.onIncrement});
}

class CounterContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, CounterViewModel>(
      converter: (store) => CounterViewModel(
        count: store.state.count,
        onIncrement: () => store.dispatch(IncrementAction()),
      ),
      builder: (context, vm) => CounterWidget(
        count: vm.count,
        onIncrement: vm.onIncrement,
      ),
    );
  }
}

The code comparison shows that FlutterExampleApps focuses on simpler implementations, while flutter_architecture_samples demonstrates more complex architectural patterns like Redux for state management.

An awesome list that curates the best Flutter libraries, tools, tutorials, articles and more.

Pros of awesome-flutter

  • Comprehensive collection of Flutter resources, libraries, and tools
  • Regularly updated with community contributions
  • Covers a wide range of topics beyond architecture patterns

Cons of awesome-flutter

  • Lacks in-depth code examples for specific architecture implementations
  • May be overwhelming for beginners due to the sheer volume of information
  • Does not provide direct comparisons between different architectural approaches

Code comparison

flutter_architecture_samples provides specific implementations of various architectures. For example, the BLoC pattern:

class TodosBloc extends Bloc<TodosEvent, TodosState> {
  TodosBloc({required this.todosRepository}) : super(TodosLoadInProgress()) {
    on<TodosLoaded>(_onTodosLoaded);
    on<TodoAdded>(_onTodoAdded);
    // ...
  }
  // ...
}

awesome-flutter, on the other hand, primarily links to external resources rather than providing code examples directly. It might include a link to a BLoC library:

- [flutter_bloc](https://github.com/felangel/bloc) - A predictable state management library that helps implement the BLoC design pattern by [Felix Angelov](https://github.com/felangel)

Summary

flutter_architecture_samples focuses on providing concrete implementations of various architecture patterns in Flutter, making it ideal for developers looking to compare and understand different approaches. awesome-flutter serves as a comprehensive resource hub for Flutter development, covering a broader range of topics but with less depth in specific architectural implementations.

17,049

A collection of Flutter examples and demos

Pros of flutter/samples

  • Officially maintained by the Flutter team, ensuring up-to-date and best practice examples
  • Covers a wide range of Flutter features and use cases
  • Includes more complex and production-ready examples

Cons of flutter/samples

  • Less focused on specific architectural patterns
  • May be overwhelming for beginners due to the large number of samples
  • Some examples might be too complex for learning basic concepts

Code Comparison

flutter/samples:

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

flutter_architecture_samples:

class HomePage extends StatelessWidget {
  HomePage({Key key, @required this.viewModel}) : super(key: key);
  final HomeViewModel viewModel;
  @override
  Widget build(BuildContext context) {
    // Implementation
  }
}

The flutter/samples code shows a more traditional StatefulWidget approach, while flutter_architecture_samples demonstrates a ViewModel pattern, emphasizing separation of concerns and testability.

11,778

A predictable state management library that helps implement the BLoC design pattern

Pros of bloc

  • More comprehensive and focused on a single architecture pattern (BLoC)
  • Extensive documentation and examples for various use cases
  • Active community and regular updates

Cons of bloc

  • Steeper learning curve for beginners due to its specific architecture
  • May be overkill for simple applications
  • Less flexibility in exploring alternative architecture patterns

Code Comparison

flutter_architecture_samples (Redux implementation):

class VisibilityFilter extends ReduxCompatible<VisibilityFilter> {
  final VisibilityFilterType activeFilter;

  VisibilityFilter(this.activeFilter);

  @override
  VisibilityFilter copyWith({VisibilityFilterType activeFilter}) {
    return VisibilityFilter(activeFilter ?? this.activeFilter);
  }
}

bloc:

class FilterBloc extends Bloc<FilterEvent, FilterState> {
  FilterBloc() : super(FilterInitial());

  @override
  Stream<FilterState> mapEventToState(FilterEvent event) async* {
    if (event is UpdateFilter) {
      yield FilterUpdated(event.filter);
    }
  }
}

The code comparison shows that bloc uses a more event-driven approach, while flutter_architecture_samples (in this case, using Redux) focuses on immutable state updates. The bloc pattern separates concerns into events, states, and the bloc itself, which can lead to more organized code in complex applications.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

flutter_architecture_samples

Build Status Build Status codecov

List of Todos Screen

TodoMVC for Flutter!

Flutter provides a lot of flexibility in deciding how to organize and architect your apps. While this freedom is very valuable, it can also lead to apps with large classes, inconsistent naming schemes, as well as mismatching or missing architectures. These types of issues can make testing, maintaining and extending your apps difficult.

The Flutter Architecture Samples project demonstrates strategies to help solve or avoid these common problems. This project implements the same app using different architectural concepts and tools.

You can use the samples in this project as a learning reference, or as a starting point for creating your own apps. The focus of this project is on demonstrating how to structure your code, design your architecture, and the eventual impact of adopting these patterns on testing and maintaining your app. You can use the techniques demonstrated here in many different ways to build apps. Your own particular priorities will impact how you implement the concepts in these projects, so you should not consider these samples to be canonical examples. To ensure the focus is kept on the aims described above, the app uses a simple UI.

Current Samples

Supporting Code

  • integration_tests - Demonstrates how to write selenium-style integration (aka end to end) tests using the Page Object Model. This test suite is run against all samples.
  • todos_repository_core - Defines the core abstract classes for loading and saving data so that storage can be implemented in various ways, such as file storage or firebase for mobile projects, or window.localStorage for web projects.
  • todos_repository_local_storage - Implements the todos repository using the file system, window.localStorage, and SharedPreferences as the data source.
  • firebase_flutter_repository - Implements the todos repository using firestore as the data source.
  • firebase_rtdb_flutter_repository - Implements the todos repository using firebase real-time database as the data source.

Running the samples

iOS / Android

cd <sample_directory>
flutter run 

Web

Make sure you're on Flutter version "Flutter 1.12.13+hotfix.6 • channel beta" or newer. Not all samples support web at this time, so please check the sample directory for a lib/main_web.dart file.

cd <sample_directory>
flutter run -d chrome -t lib/main_web.dart

Why a todo app?

The app in this project aims to be simple enough that you can understand it quickly, but complex enough to showcase difficult design decisions and testing scenarios. For more information, see the app's specification.

Be excellent to each other

This Repo is meant as a discussion platform for various architectures. Let us debate these ideas vigorously, but let us be excellent to each other in the process!

While healthy debate and contributions are very welcome, trolls are not. Read the code of conduct for detailed information.

Contributing

Feel free to join in the discussion, file issues, and we'd love to have more samples added! Please read the CONTRIBUTING file for guidance :)

License

All code in this repo is MIT licensed.

Attribution

All of these ideas and even some of the language are directly influenced by two projects:

Contributors

I'd like to thank all of the folks who have helped write new samples, improve the current implementations, and added documentation! You're amazing! :)