Flutter

From bibbleWiki
Jump to navigation Jump to search

Introduction

Why Flutter created in 2017

  • Compiles to native, JIT and Ahead of Time
  • Fast Development
  • Single Code Base
  • Uses Dart

Resources is https://github.com/simoales/flutter

Installation

Flutter

You can switch versions of flutter using the channel option where there are options of master, dev, beta etc. See https://github.com/flutter/flutter/wiki/Flutter-build-release-channels

sudo snap install flutter --classic
sudo snap install flutter-gallery
flutter channel dev
flutter upgrade
flutter config --enable-linux-desktop

You will need to specify the path to android studio

flutter config --android-studio-dir="/opt/android-studio-4.1/android-studio"

Android Studio

For Android Studio the flutter SDK will be in /home/(username)/snap/flutter/common/flutter

Flutter doctor

You can run flutter doctor to see if all went well. This is what I got

flutter doctor
[] Flutter (Channel dev, 1.25.0-8.0.pre, on Linux, locale en_NZ.UTF-8)
[] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[] VS Code (version 1.52.0)
[] Connected device (1 available)

Creating a Project

In VS Code run flutter doctor and then flutter new project. Project names must be in lower case. e.g. hello_flutter. This opens a new VS Code with the project. The import contains the widgets to use and the rest just configures the widgets on the screen. I.E. Text is like a <Text /> tag in react or angular.

import 'package:flutter/material.dart';

void main() {
  runApp(Center(
    child: Text("Fred Was Ere",
        textDirection: TextDirection.ltr,
        style: TextStyle(backgroundColor: Colors.blue)),
  ));
}

When familar we can create a project with the flutter cli

flutter create app_widgets

A Bigger Example

So a bigger example might be

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: "My lovely App",
    home: Scaffold(
      appBar: AppBar(
        title: Text("App Bar Title"),
      ),
      body: Material(
        color: Colors.deepPurple,
        child: Center(
          child: Text(
            "Fred Was Ere",
            textDirection: TextDirection.ltr,
            style: TextStyle(color: Colors.white, fontSize: 36.0),
          ),
        ),
      ),
    ),
  ));
}

Classes

Things are getting a big large so we need to break the code down. We do this by writing our own classes. We can derive a class from StatelessWidget to do this.

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "My lovely App",
      home: Scaffold(
        appBar: AppBar(
          title: Text("App Bar Title"),
        ),
        body: Material(
          color: Colors.deepPurple,
          child: Center(
            child: Text(
              "Fred Was Ere",
              textDirection: TextDirection.ltr,
              style: TextStyle(color: Colors.white, fontSize: 36.0),
            ),
          ),
        ),
      ),
    );
  }
}

Fat Arrow

Dart supports the fat arrow approach so we can so

import './screens/home.dart';

void main() {
  runApp(MyWidget());
}

Can become

import './screens/home.dart';

void main() => runApp(MyWidget());

Adding Logic

No surprises here. We can add functions within the class declaration.

import 'package:flutter/material.dart';

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.deepPurple,
      child: Center(
        child: Text(
          sayHello(),
          textDirection: TextDirection.ltr,
          style: TextStyle(color: Colors.white, fontSize: 36.0),
        ),
      ),
    );
  }

  String sayHello() {
    var hello;
    DateTime now = DateTime.now();
    if (now.hour < 12) {
      hello = "Good Morning";
    } else if (now.hour < 18) {
      hello = "Good Afternoon";
    } else {
      hello = "Good Evening";
    }
    return hello;
  }
}

Basic Widgets and Concepts

The basic widgets and Concepts are

  • Container
  • Text
  • Row & Column
  • Image
  • RaisedButton
  • AlertDialog
  • Box Constraints
  • Size, Margin and Padding

Containers

They are as they sound. It is worth noting the width and height are controlled by the parent. Look at https://flutter.io/layout. To bypass the constraint of the parent you need to wrap your widget in a widget which supports this. E.g. Center widget.

import 'package:flutter/material.dart';

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
      width: 192.0,
      height: 96.0,
      alignment: Alignment.center,
      color: Colors.deepOrangeAccent,
      child: Text(
        "Pizza",
        textDirection: TextDirection.ltr,
      ),
    ));
  }
}

Margins And Padding

Margins and Paddings use the EdgeInsets.All and EdgeInsets.Only constructor. So to set a margin we can do.

...
        child: Container(
      width: 192.0,
      height: 96.0,
      margin: EdgeInsets.only(left:50.0),
      padding: EdgeInsets.All(10.0),
...

Fonts

Copy the fonts to a directory. The file pubspec.yaml contains the configurations.

  fonts:
    - family: Oxygen
      fonts:
        - asset: fonts/Oxygen-Regular.ttf
        - asset: fonts/Oxygen-Bold.ttf
          weight: 700
        - asset: fonts/Oxygen-Light.ttf
          weight: 300

Now we can use the font with the Text Widget

...
      child: Text(
        "Pizza",
        textDirection: TextDirection.ltr,
        style: TextStyle(
          fontFamily: 'Oxygen',
          fontWeight: FontWeight.w300,
        ),
...

Rows and Columns

These seem to work the same as flex box.

...
        child: Row(
          children: <Widget>[
            Text(
              "Margherita",
              textDirection: TextDirection.ltr,
              style: TextStyle(
                fontFamily: 'Oxygen',
                fontWeight: FontWeight.w300,
              ),
            ),
            Text(
              "Tomato, Mozzarella, Basil",
              textDirection: TextDirection.ltr,
              style: TextStyle(
                fontFamily: 'Oxygen',
                fontWeight: FontWeight.w300,
              ),
            ),
          ],
        ),
...

The result is items which overflow the row because the text exceeds the width of the phone.


Wrapping in Expanded means that the row will wrap like flexbox wrapping.

            Expanded(
              child: Text(
                "Tomato, Mozzarella, Basil",
                textDirection: TextDirection.ltr,
                style: TextStyle(
                  fontSize: 30,
                  fontFamily: 'Oxygen',
                  fontWeight: FontWeight.w300,
                ),
              ),
            ),

Expanded