All Projects → Jahidul007 → Flutter_Roadmap

Jahidul007 / Flutter_Roadmap

Licence: other
This is a flutter roadmap and documentation repository. If anyone is interested you can join the party to help the community and make flutter great again.

Programming Languages

dart
5743 projects

Projects that are alternatives of or similar to Flutter Roadmap

Bloc
A predictable state management library that helps implement the BLoC design pattern
Stars: ✭ 8,214 (+17376.6%)
Mutual labels:  state-management, bloc
random-users-details
Random Users details in flutter from randomusers api
Stars: ✭ 14 (-70.21%)
Mutual labels:  state-management, provider
awesome-software-architecture
A curated list of awesome articles, videos, and other resources to learn and practice software architecture, patterns, and principles.
Stars: ✭ 1,594 (+3291.49%)
Mutual labels:  clean-architecture, ddd-architecture
flutter-bloc-patterns
A set of most common BLoC use cases built on top of flutter_bloc library
Stars: ✭ 58 (+23.4%)
Mutual labels:  state-management, bloc
last fm
A simple app to demonstrate a testable, maintainable, and scalable architecture for flutter. flutter_bloc, get_it, hive, and REST API are some of the tech stacks used in this project.
Stars: ✭ 134 (+185.11%)
Mutual labels:  clean-architecture, bloc
Getx
Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
Stars: ✭ 5,578 (+11768.09%)
Mutual labels:  state-management, getx
generic bloc provider
Generic BloC provider implementation
Stars: ✭ 26 (-44.68%)
Mutual labels:  state-management, bloc
bloc samples
A collection of apps built with the Bloc library.
Stars: ✭ 39 (-17.02%)
Mutual labels:  state-management, bloc
bloc
A predictable state management library that helps implement the BLoC design pattern
Stars: ✭ 12 (-74.47%)
Mutual labels:  state-management, bloc
flutter-provider-architecture
⚖️ A Flutter Architecture for small/medium/large/big large scale using Provider as State Management with Get It!
Stars: ✭ 81 (+72.34%)
Mutual labels:  state-management, provider
flutter expense manager
Flutter Provider and Shared Preferences Sample Application.
Stars: ✭ 59 (+25.53%)
Mutual labels:  state-management, provider
nstate
A simple but powerful react state management library with low mind burden
Stars: ✭ 11 (-76.6%)
Mutual labels:  state-management, ddd-architecture
reactube-client
A clone Youtube Web Player using React Provider Pattern, React Context and Typescript
Stars: ✭ 92 (+95.74%)
Mutual labels:  state-management, provider
Provider
InheritedWidgets, but simple
Stars: ✭ 3,988 (+8385.11%)
Mutual labels:  state-management, provider
UseCases
This a library that offers a generic implementation of the data layers from the clean architecture by Uncle bob.
Stars: ✭ 23 (-51.06%)
Mutual labels:  state-management, clean-architecture
rtu-mirea-mobile
A mobile application for the MIREA - Russian Technological University, which includes a schedule, news and many other functions
Stars: ✭ 80 (+70.21%)
Mutual labels:  clean-architecture, bloc
flutter preload videos
Preloading videos in Flutter 💙
Stars: ✭ 42 (-10.64%)
Mutual labels:  provider, bloc
flutter-clean-arch
A flutter's implementation of a "clean architecture"
Stars: ✭ 149 (+217.02%)
Mutual labels:  provider, bloc
nodejs-hexagonal-architecture-and-unit-test
This is a project to explain hexagonal architecture and unit tests in node.js
Stars: ✭ 99 (+110.64%)
Mutual labels:  clean-architecture, ddd-architecture
eShopOnWeb
Sample ASP.NET Core 6.0 reference application, powered by Microsoft, demonstrating a layered application architecture with monolithic deployment model. Download the eBook PDF from docs folder.
Stars: ✭ 8,250 (+17453.19%)
Mutual labels:  clean-architecture, ddd-architecture

Flutter_Road_Map_Documentation

Flutter-road-map

Content

Courses

Flutter Clean Architechture

Data

The Data layer consists of repository and data models. Repository is where the application gather all data related to the use case, either from local sources (Local DB, cookies) or remote sources (remote API). Data from the sources, usually in json format, is parsed to Dart object called models. It’s need to be done to make sure the application knows what data and variable it’s expecting.

Domain

Domain is the inner layer which shouldn’t be susceptible to the whims of changing data sources or porting our app to Angular Dart. It will contain only the core business logic (use cases) and business objects (entities).

Repository classes act as the Data Layer and Domain Layer, each function on the repository class acts as the domain layer that specifies the use cases of the feature.

Presentation

Presentation is where the UI goes. You obviously need widgets to display something on the screen. These widgets is controlled by the state using various state management design pattern used in Flutter. In this project, I use BLoC as the state management.

BLoC allows us to know exactly what data is given to the state. There is BLoC implementation that uses event classes to easily predict what state is the application in, but I use the simpler implementation of BLoC (just using streams) to shorten times for other that hasn’t been familiar to BLoC before. But I won’t dive too deep on BLoC because it’s another thing to write

FLutter Clean Architechture

Code to generate the folder pattern

import 'dart:convert';
import 'dart:io';

void main(List<String> arguments) async {
  Map<String, List<String>> directoryList = {
    'Data': [
      'RepositoryModels',
      'Repositories/LocalRepository',
      'Repositories/RemoteRepository',
    ],
    'Domain': [
      'Entities',
    ],
    'Presentation': [
      'Controllers',
      'Utilities',
      'Widgets',
      'Functions',
      'Language',
      'Pages',
    ],
  };
  //Add your the list of pages in your app/website

  List<String> pageList = [
    /*Sample List*/
    "OnBoardings",
    "Sign In",
    "Sign Up",
    "Home",
    "Item List",
    "Settings",
    "Help",
    "Chat"
  ];

  ///Creating the directories
  await directoryList.forEach((key, value) async {
    await directoryList[key].forEach((element) async {
      await makeFile("$key/$element/export" +
          "${element.replaceAll(' ', '_').toLowerCase()}.dart");
    });
  });

  ///Creating the Functions and Widgets directories in every pages
  await pageList.forEach((element) async {
    ///Create The Page Folder
    await makeFile("Presentation/Pages/" +
        "${element.toLowerCase()}/${element.replaceAll(' ', '_').toLowerCase()}Page.dart");

    ///Create The Page's Functions Folder
    await makeFile(
        "Presentation/Pages/${element.toLowerCase()}/Functions/${element.replaceAll(' ', '_').toLowerCase()}Functions.dart");

    ///Create The Page's Widgets Folder
    await makeFile(
        "Presentation/Pages/${element.toLowerCase()}/Widgets/${element.replaceAll(' ', '_').toLowerCase()}Widgets.dart");

    ///Add The page in the export file
    await File("Presentation/Pages/exportpages.dart").writeAsStringSync(
      "export '${element.toLowerCase()}/${element.replaceAll(' ', '_').toLowerCase()}Page.dart';\n",
      mode: FileMode.append,
    );
  });

  // print("Export Pages:\n" + exportPages);
}

makeDir(String s) async {
  var dir = await Directory(s).create(recursive: true);
  // print(dir.path);
}

makeFile(String s) async {
  var dir = await File(s).create(recursive: true);
  // print(dir.path);
}

Feature Driven Project Architecture

  ├── lib
  |   ├── posts
  │   │   ├── bloc
  │   │   │   └── post_bloc.dart
  |   |   |   └── post_event.dart
  |   |   |   └── post_state.dart
  |   |   └── models
  |   |   |   └── models.dart*
  |   |   |   └── post.dart
  │   │   └── view
  │   │   |   ├── posts_page.dart
  │   │   |   └── posts_list.dart
  |   |   |   └── view.dart*
  |   |   └── widgets
  |   |   |   └── bottom_loader.dart
  |   |   |   └── post_list_item.dart
  |   |   |   └── widgets.dart*
  │   │   ├── posts.dart*
  │   ├── app.dart
  │   ├── simple_bloc_observer.dart
  │   └── main.dart
  ├── pubspec.lock
  ├── pubspec.yaml

The application uses a feature-driven directory structure. This project structure enables us to scale the project by having self-contained features. In this example we will only have a single feature (the post feature) and it's split up into respective folders with barrel files, indicated by the asterisk (*).

Reactive Programming with MVVM pattern

It basically consists of three layers where the View which consists of all UI elements you see on the screen. It can also contain logic that only concerns the UI. The Model contains your business logic and backend connections. The ViewModel is the glue between both in that it processes and transforms data from the Model to a form the View can easily display. It offers functions (often called Commands) the View can call to trigger actions on the Model and provides events to signal the View about data changes.

Important: The ViewModel knows nothing about the View which makes it testable and more than one View can use the same ViewModel. A ViewModel just offers services to the View (events, commands). The _View decides which it uses.

"Several MVVM frameworks encapsulate the subscription of events and calling functions to update data in the ViewModel from the View using DataBindings"

To trigger any other action in the View besides data updates from the ViewModel gets tedious because you have to publish events and functions if the View should be able to retrieve data as a result of the event.

Another problem is that we always moving state between the different layers which have to be kept in sync.

What we really want is an App that just reacts on any event from the outside without having to deal with state management all the time.

MVVM

code Snippet

  • Dismissable item from listview onClick
onClick:(){
  removeItem(index);
}

 void removeItem(index) {
    setState(() {
      groupData.removeAt(index);
    });
  }

N.B: Must be followed stateful widget.

  • Reorderable List
 void onReorder(int oldIndex, int newIndex) {
    if (newIndex > oldIndex) {
      newIndex -= 1;
    }
    setState(() {
      String game = topTenGames[oldIndex];

      topTenGames.removeAt(oldIndex);
      topTenGames.insert(newIndex, game);
    });
  }
  • iso8601 date/time convert to standard format
 var date = "2021-03-24T08:57:47.812" 
 var dateTime =  DateTime.parse("${date.substring(0,16)}");
 var stdTime =  DateFormat('MMM d, yy hh:mm a').format(dateTime).toString();
  • convert tiem to local
var dateFormat = DateFormat("dd-MM-yyyy hh:mm aa"); // you can change the format here
var utcDate = dateFormat.format(DateTime.parse(uTCTime)); // pass the UTC time here
var localDate = dateFormat.parse(utcDate, true).toLocal().toString();
String createdDate = dateFormat.format(DateTime.parse(localDate)); 
  • List to map of map
List<String> _options = [
 'Arts & entertainment',
 'Biographies & memoirs',
];

List<bool> _isOptionSelected = [
 false,
 false,
];



Map<String, dynamic> map =  _options.asMap().map((key,value)=>MapEntry(value,{
 'optionName':value,
 'isOptionSelected':_isOptionSelected[key]
}));
  • map of map to list

List<String> _options = [];
 List<bool> _isOptionSelected = [];
 Map<String, Map<String, dynamic>> _isOptionMap = {
   'Arts & entertainment': {
     'optionName': 'Arts & entertainment',
     'isOptionSelected': false,
   },
   'Biographies & memoirs': {
     'optionName': 'Biographies & memoirs',
     'isOptionSelected': false,
   },
 };
 _isOptionMap.forEach((key, value) {
     _options.add(value['optionName']);
     _isOptionSelected.add(value['isOptionSelected']);
   
 });
 print(_options);
 print(_isOptionSelected);
  • How can I limit the size of a text field in flutter?
TextEditingController _controller = new TextEditingController();
String text = ""; // empty string to carry what was there before it 
onChanged
int maxLength = ...
...
new TextField(
 controller: _controller,
 onChange: (String newVal) {
     if(newVal.length <= maxLength){
         text = newVal;
     }else{
         _controller.value = new TextEditingValue(
             text: text,
             selection: new TextSelection(
                 baseOffset: maxLength,
                 extentOffset: maxLength,
                 affinity: TextAffinity.downstream,
                 isDirectional: false
             ),
             composing: new TextRange(
                 start: 0, end: maxLength
             )
         );
         _controller.text = text;
     } 
 }
);
  • Date picker with time
DateTimePicker(
                   type: DateTimePickerType.dateTimeSeparate,
                   dateMask: 'yyyy-MM-dd',
                   initialValue: DateTime.now().toString(),
                   firstDate: DateTime(2000),
                   lastDate: DateTime(2100),
                   icon: Icon(Icons.event),
                   dateLabelText: 'Date',
                   timeLabelText: "Hour",

                   onChanged: (val) {
                     var date = val.substring(0,10);
                     var time = val.substring(11);
                     reportBloc.updateFromDate(date+"T"+time+":00.000Z");
                   },
                   validator: (val) {
                     return null;
                   },
                   onSaved: (val) {
                     reportBloc.updateFromDate(val);
                   },
                 ),
  • initialize alertBox when app open
WidgetsBinding.instance.addPostFrameCallback((_) async {
   await showDialog(
     context: context,
     builder: (BuildContext context) => AnimatedPadding(
       padding: MediaQuery.of(context).viewInsets,
       duration: const Duration(milliseconds: 100),
       curve: Curves.decelerate,
       child: LoadingWrap(
         padding: EdgeInsets.all(20),
         children: [
           new AlertDialog(
             insetPadding: EdgeInsets.all(20),
             contentPadding: EdgeInsets.all(0),
             content: Container(
               height: 200,
               width: MediaQuery.of(context).size.width,
               child: SingleChildScrollView(
                 child: ListBody(
                   children: <Widget>[
                    -------------
                         ],
                       ),
                     ),
                   ],
                 ),
               ),
             ),
             actions: <Widget>[],
           )
         ],
       ),
     ),
   );
 });
  • Tooltip onTap rather than onLongPress possible?
GestureDetector(
         onTap: () {
           final dynamic _toolTip = _toolTipKey.currentState;
           _toolTip.ensureTooltipVisible();
         },
         child: Tooltip(
           key: _toolTipKey,
           waitDuration: Duration(seconds: 1),
           showDuration: Duration(seconds: 2),
           padding: EdgeInsets.all(5),
           height: 16,
           message: widget.message??"testing tooltip",
           child: SvgPicture.asset("images/ic_info.svg"),),
       ),
     ],),
   )
   
  • Get Customize phone number format
//flutter_masked_text: ^0.8.0
import 'package:flutter_masked_text/flutter_masked_text.dart';

String getPhoneNumber(String phoneNum)  {
 var controller = new MaskedTextController(text: '', mask: '000-0000');
 controller.updateText(phoneNum);
 return controller.text.length >=1 ?"1-868-"+controller.text:"Not Available";
}
  • swap list value
balanceTransferDescription
         .where((element) => element.name.toLowerCase().contains("other"))
         .forEach((element) {
       balanceTransferDescription.remove(element);
       balanceTransferDescription.insert(
           balanceTransferDescription.length, element);
  • Capitalize first letter of the first word for each sentence
String capitalizeSentence(String s) {
  // Each sentence becomes an array element
  var sentences = s.split('.');
  // Initialize string as empty string
  var output = '';
  // Loop through each sentence
  for (var sen in sentences) {
    // Trim leading and trailing whitespace
    var trimmed = sen.trim();
    // Capitalize first letter of current sentence
    var capitalized = "${trimmed[0].toUpperCase() + trimmed.substring(1)}";
    // Add current sentence to output with a period
    output += capitalized + ". ";
  }
  return output;
}
  • Dart remove all brackets with integers between them
String s = "Hello, world![1] i am 'foo' [100]";
print(s.replaceAll(new RegExp(r'\s*\[\d+]'),''));
  • Remove duplicate value from map
import 'dart:collection';

void main() {
  List users = [
    {"userEmail": "[email protected]"},
    {"userEmail": "[email protected]"},
    {"userEmail": "[email protected]"},
    {"userEmail": "[email protected]"},
    {"userEmail": "[email protected]"},
  ];

  var finalList = [
    ...LinkedHashSet(
      equals: (user1, user2) => user1['userEmail'] == user2['userEmail'],
      hashCode: (user) => user['userEmail'].hashCode,
    )..addAll(users)
  ];
  print(finalList);
}
  • Call secondary color from theme data
// define theme
theme: ThemeData(
          primaryColor: Colors.black,
          colorScheme: ColorScheme.fromSwatch().copyWith(
            secondary: Colors.green,
          ),
        ),
 // call color 
 color: Theme.of(context).colorScheme.secondary
  • Indentical methond in double, string, list

You got the false because a list is an indexable collection of objects with a length. In identical checks, two instances are the same or not but you can convert this instance into a string.

  List l1 = [1, 2, 3, 4];
  List l2 = [1, 2, 3, 4];
  print(identical(l1.toString(), l2.toString())); //true

For list comparison, you can use listEquals

import 'package:flutter/foundation.dart';
void main() {
  List<int> l1 = [1, 2, 3,4];
  List<int> l2 = [1, 2, 3, 4];
  print(listEquals(l1, l2)); //true
}

Issue and Error Handling

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].