Skip to content

singh1aryan/Intro-to-Flutter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

72 Commits
ย 
ย 
ย 
ย 

Repository files navigation

All About Flutter

  • If you want to know about open source, hackathons, mobile development, personal projects -> this is the right place for you. Documenting Flutter for the community.

Introduction

  • What's Flutter - Cross native platform to build Mobile applications
  • Easy to get started, perfect for hackathons, super fast to code!

Things you need to know before coming here -

  • print() function in any programming language

Getting started

Android, Flutter, react native

Flutter vs Other technologies

Flutter vs Android

  • For people who already know Android:

  • UI - Android needs XML integration whereas everything is a Widget in Flutter and can be made in a single file

  • Listeners No more listeners for onclicks, call the methods, change the state and enjoy the view

  • findView - No more findViewById() - just do everything inside the Widget(){} and leave the finding to Android

  • Gradle - No more gradle issues - add dependencies in the pubspec.yaml file and refresh the application to use the new libraries

  • Assets - Have to be managed separately in Flutter, you have to declare everything you use - For eg: images, fonts. In android, you can simply add it in the file section and use them.

  • Animations are much much easier and well supported in Flutter - Basic Uses - Eg: Splash activity, Swiping tabs, results, analytics page, navigation

  • Running the app - Hot reloading in Flutter - just hit 'r' for a reload and 'R' for a restart of the application. Android studio can take upto 20-30 seconds for each reload, and even more if there are gradle issues, which popup every once a while

  • API - Android APIs can be done with different libraries like Retrofit using GSON whereas fetching in Flutter can be done without any pain. The common Fetch function can be used in Flutter and have async await methods to call the APIs.

  • Recycler/List view - Recycler View is used in Android to create different lists on a screen. We need an adapter for that which has an interface and we need to know all sorts of different functions to completely implement it. Flutter just has a widget for a ListView where we can define different ListTiles or just add stuff dynamically. Much easier, looks simpler.

  • Learning Curve - Working in Flutter is easier once you know dart, which is similar to javascript, and understand the basic concepts about Widgets. Android allows you to make layouts with the help of the designer, which can be used to make constraint layouts. Making basic applications are definitely easier to learn in Android but as we go deeper in fragments and other stuff, it starts to get complicated

  • Fragments vs Components(widgets) - we can simply use the widget component wherever we want unlike the fragments we make in Android, which require some knowledge before hand on how to use Bundle, adapters, xml layouts, and different methods like onCreateView and layoutInflator

  • SQl database - It's pretty similar in both the technologies. The only difference is that state management can come into place if you're trying to add something consecutively, you would have to store the key in the state and change it using setState(){_key+=1} -> just a use case. The room library in Android is pretty wide used and easy to implement as well

  • Architecture patterns - Everything boils down to MVP/ MVVM/ MVC in Android, whereas we have BloC and Providers in Flutter, which do something similar to MVC, separating out the business logic by creating sinks and streams

  • Code Editor - VSCode/Android studio - Flutter and Android studio for android

  • Getting started guide - Pretty straighforward for Android, download the studio and get started, whereas you have to do a bunch of things for Flutter - can be annoying

Firebase - Resources for Flutter Firebase: -

Flutter vs React-Native

  • UI - Flutter and RN have a one file system, where you define the rules and UI. I personally like the interface for Flutter apps as it's much more defined. It's also maintained by Google which owns Android and can have a much better integration with Google.

  • Classes - Flutter uses Widgets for literally everything, from TextViews to TabViews - they're called 'Widgets'. Flutter uses dart, whereas React native uses Typescript or javascript.

  • Components - RN has components and we have to import them from 'react-native' to use them. Flutter has widgets which can be used in a similar space. Both of them are similar except the styling and the rendering part.

  • Styling Flutter - inside widgets - so if you want padding => you wrap the widget in Padding() widget with some padding, React Native: you define const style: Stylesheet and add your styles there - similar to the web style where you have css. So react native has css styling whereas Flutter has the 'widget' styling

  • Animations - Flutter is much easier to grasb, whereas react native has a wider aspect to it

  • Learning Curve - Similar in React native and Flutter.

  • Libraries - npm helps in react native whereas for flutter we just add them to the pubspec.yaml file

  • APIs - Both of them have a clear vision on using APIs. A good article for RN - https://medium.com/better-programming/handling-api-like-a-boss-in-react-native-364abd92dc3d

  • Code Editor - VS code is popular for both

  • Getting started - Personally, it's been really really hard to work with react native on windows. It's much better if you use a mac, but overall that red screen annoys you a lot. Flutter doesn't have the easiest getting started guide, but there is support out there to help you.

  • Overall - Both can make cross native apps and I'll choose Flutter anyday - hackathons/quick projects/learn android as well, and React native - web/ learn react.js/ -> if you want to stress yourself :P

  • The best way to get started is to work with real life applications with some source code in hand
  • You download a starter code and then build from there. Start with an easy project, move your way up and change things as you go
  • Covers everything from Basic layouts to Google maps or advanced UI

Everything is a Widget in Flutter

Multi-child layout widgets

  • Text
  • Row - children - Expanded
  • Column
  • Center
  • Container - child, decoration
  • Stack
  • Tab View, Grid View
  • Expanded
  • Icon Button
  • Raised Button
  • Image.asset
  • List View, List Tile
  • Table
  • Wrap

Single-child layout widgets

  • Slivers
  • SliverList
  • SliverGrid
  • SliverAppBar
  • DeMystified

Styling

  • Padding
  • Align
  • Aspect Ratio
  • Baseline -
  • Center
  • Constraint Box
  • Container
  • Fitted Box
  • Intrinsic Height, Weight
  • Offstage
  • Transform

Important Diagrams

Screen Shot 2019-10-06 at 10 22 10 PM

Screen Shot 2019-10-06 at 10 41 15 PM

Screen Shot 2019-10-06 at 10 41 25 PM

Async/Await with Flutter

fetch() async {

    var url = "API-HERE";
    var res = await http.get(url);
    var body = jsonDecode(res.body);

    // body is your API body 
}

Machine Learning with Flutter

  • Using the ML Kit with Flutter

Firebase + Flutter

  • Firebase auth - login with google or Oauth
  • Firebase Firestore - Realtime database
  • Firebase push notifications - Notify the user when a new recipe is added
  • Firebase analytics - how the app in performing
  • Firebase ML kit - built in ml models for text, face recognition

Accessibility Coding - Flutter vs Android

  • Exclude Semantics
  • Merge Semantics
  • Voice Overs
  • Color Combination
  • It's much more defined in Android, but definitely coming up in Flutter
  • For example: We can add things like content description to a button, textView etc in Android for voice overs

Problems - Flutter issues

Navigation - Flutter

  • Navigation is really easy, and if you know OOPS, then you'll master it in seconds
  • You just need to pass in the object and that's it. Pass it everywhere (literally!) - for the basics
  • Any data is passed in an Object which can be parsed in the next class

Firebase Functions - Notifications

  • Implemented fully optimized firebase functions and push notifications
  • The user is notified in real time when a new item is added to the recipes_list
  • Used Node JS and TypeScript to create a firebase function which does this

Example Widget - Tab Views - Android vs Flutter

  • Again, everything including this is very straightforward in Flutter
  • Make a Tab View, fill in the required parameters and you're all set
  • Tab Controller, TabBar for the Labels and TabBarView for the actual stuff in each tab
  • You could add literally any widget in there - Text, ListView etc
  • It's a bit more complex and well defined in Android
  • We need view pagers, adapters, and fragments to add a tab view
  • We can have different UIs for the fragments, but it's more time consuming to understand and implement

Computer vision ML integration

  • We can integrate a machine learning model to predict the food/recipe posted
  • We can probably look at a dataset of recipes and predict if it's going on the right path
  • Merging the ML code soon!

BloC pattern

https://steemit.com/utopian-io/@tensor/advanced-flutter-project---best-practices---generic-bloc-providers---part-three

Open source Flutter Apps

Awesome GitHub people

Other resources

Different Code snippets -> Beginner - Intermediate - Advanced

Basic class layout

class App extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Home(),
      theme: ThemeData(primaryColor: PrimaryColor),//add-your-color here || or remove this
      debugShowCheckedModeBanner: false,
    );
  }
}

class Home extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new _HomeState();
  }
}

class _HomeState extends State<Home>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column()
    );
}

Simple widgets -> widgets folder in lib

Using conditionals with Flutter

child: users.length <= 0
            ? Center(
                child: EmptyState(
                  title: 'Oops',
                  message: 'Add form by tapping add button below',
                ),
              )
            : ListView.builder(
                addAutomaticKeepAlives: true,
                itemCount: users.length,
                itemBuilder: (_, i) => users[i],
              ),
      )

APIs - Flutter

Simple API fetch function

fetch() async {

    var url = "API-HERE";
    var res = await http.get(url);
    var body = jsonDecode(res.body);

    // body is your API body 
}

Parsing API - Eg: staggered tile

for(int i=0;i<body[0]['staggered_tiles'].length;i++){
    _staggeredTiles.add(new StaggeredTile.count(
      body[0]['staggered_tiles'][i]['cross_axis'],// body is what we get from the API
      body[0]['staggered_tiles'][i]['main_axis']// body is what we get from the API
    ));
}     

Parsing 2 APIs in one - Eg: pager view

if (body[i][0]['type'] == 'donut') {
        List<LabelPieSales> _d = [];
        for (int j = 0; j < body[i][0]['data'].length; j++) {
          _d.add(new LabelPieSales(
              body[i][0]['data'][j]['year'], body[i][0]['data'][j]['sales']));// body is what we get from the API
        }
        _wid_top.add(new Container(
          height: 200,
          width: 200,
          child: DonutChartWidget.withSampleData(_d),
        ));
      }
      else if (body[i][0]['type'] == 'label-pie') {
        List<LabelPieSales> _d = [];
        for (int j = 0; j < body[i][0]['data'].length; j++) {
          _d.add(new LabelPieSales(
              body[i][0]['data'][j]['year'], body[i][0]['data'][j]['sales']));// body is what we get from the API
        }
        _wid_top.add(new Container(
          height: 200,
          width: 200,
          child: SimpleBarChart.withSampleData(_d),
        ));
      }

API with Notifier - Eg: real time interaction with buttons and API

return Container(
      padding: const EdgeInsets.all(4.0),
      child: appState.isFetching
          ? CircularProgressIndicator()
          : appState.getResponseJson() != null
          ? ListView.builder(
              primary: false,
              shrinkWrap: true,
              itemCount: appState.getResponseJson().length,
              itemBuilder: (context, index) {
                return Container(
                  height: 100,
                  width: 100,
                  child: graph(appState.getResponseJson()),
                );
              },
            )
          : Text("Press Button above to fetch data"),
    );

SQL database + Flutter

Initializing SQL database

initDB() async {
  return await openDatabase(
    join(await getDatabasesPath(), 'graphs_database.db'),
    onCreate: (db, version) {
      return db.execute(
        "CREATE TABLE graphs(id INTEGER PRIMARY KEY, type TEXT)",
      );
    },
    version: 1,
  );
}

State management - Eg: adding new objects in SQL database

floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () async {
          Dog dog = new Dog(id: _id, name: "name",age: 22);
          await insertDog(dog);
          setState(() {
            _id += 1;
          });
        },
      ),

Comparing SQL and API stuff - making a local push notification

List<Graph> graphs_sql = await graphs();
            List<String> graphs_sql_types = [];
            for(int i=0;i<graphs_sql.length;i++){
              graphs_sql_types.add(graphs_sql[i].type);
            }
            if (graphs_sql.length != _types.length) {
              for (int i = 0; i < _types.length; i++) {
                if(!graphs_sql_types.contains(_types[i])){ // add only if a new type
                  await insertGraph(new Graph(id: i, type: _types[i]));
                }
              }
            }

Web views for Flutter - Eg: Displaying websites inside your app

launchUrl() {
    setState(() {
      urlString = controller.text;
      flutterWebviewPlugin.reloadUrl(urlString);
    });
  }

Class Layouts

class News{
  String dateAdded;
  String title;
  String body;
  String level;
  String category;

  News(this.dateAdded, this.title, this.body, this.level, this.category);

}

class Record {
  final String name;
  final int votes;
  final DocumentReference reference;

  Record.fromMap(Map<String, dynamic> map, {this.reference})
      : assert(map['name'] != null),
        assert(map['votes'] != null),
        name = map['name'],
        votes = map['votes'];

  Record.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, reference: snapshot.reference);

  @override
  String toString() => "Record<$name:$votes>";
}

Height and Width of screen

double _height = MediaQuery.of(context).size.height;
double _width = MediaQuery.of(context).size.width;

init state - initialize any lists/images for the screen

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    _image = {url};
    localList1 = globalList1;
    localList1 = globalList2;
    }

Firebase stuff:

Firebase Function- Eg: push notifications

export const sendToTopic = functions.firestore
    .document('recipes/{recipyId}')
    .onCreate(async snapshot => {
        // const recipe = snapshot.data();
        const payload : admin.messaging.MessagingPayload = {
            notification: {
                title: 'new recipe added, check it out',
                body: 'Make it and eat it'
            }
        };

        return fcm.sendToTopic('recipes', payload);
    });

Firebase Firestore

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Recipes for you')),
      body: _buildBody(context),
    );
  }

  Widget _buildBody(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('recipes').snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return LinearProgressIndicator();
        return _buildList(context, snapshot.data.documents);
      },
    );
  }

Intgerating Asymmetric view with Firestore

  • Google Codelabs gave me the Asymmetric view, and I wanted to combine it with Firestore
  • It's definitely tricky as you can show data directly from the Firestore to a Listview, but you can store it and send the whole list to another class
  • List<Recipe> recipe_list = [];
    //    snapshot.map((data) => recipeList(context, data).toList());
    for(int i=0;i<snapshot.length;i++){
      Recipe recipe = Recipe.fromSnapshot(snapshot[i]);
      recipe_list.add(recipe);
    }
    return AsymmetricView(products: recipe_list,);
    

Apps

Practice by making these Apps

  • API: News, Movies, Restaurants
  • Social Media: Blogs, Recipes
  • Games: Tic-Tac-Toe, Minesweeper, Guessing Cards, 2048, 15
  • Animations: Tinder cards, Sliding, Modals, Rainfall, Pizza maker, Payment System
  • Simple: Todo, Navigation, Login, Drawers
  • UI: Dashboard, Payment system, Shopping, Recipe design
  • Machine learning: Text to Speech, Computer vision, Chatbots

NATIVE DEVELOPMENT

  • So if you're coding in react native or flutter and want to use a 3rd party library such as arcgis-maps for the Map component in your app, you would have to make a bridge between the UI and the native side of the development - which means that the specific API or library would've to be coded separately in ios and android with the specific documentation for each.
  • More coming on this.

Hackathons

Why to use Flutter?

  • Quick API integration - fetching, parsing, using
  • Using Networking, web sockets, chatting features
  • Using Open Source material design for interactive UI
  • Take advantage of Open source projects - for UI
  • Firebase quick integration - notification, login, database
  • Machine learning kit powered by Firebase - MLKit
  • Computer vision library by MLKit

Useful Blog posts

Important!

  • Feel free to make a pull request if you find something wrong/ can be improved
  • Don't forget to star or fork the repo, I add things every once a while