The basics

Domains: Flutter

How do I create a Flutter app?

To create an app using React Native, you would run create-react-native-app from the command line.

$ create-react-native-app <projectname>

To create an app in Flutter, do one of the following:

  • Use an IDE with the Flutter and Dart plugins installed.
  • Use the flutter create command from the command line. Make sure that the Flutter SDK is in your PATH.
$ flutter create <projectname>

For more information, see Getting Started, which walks you through creating a button-click counter app. Creating a Flutter project builds all the files that you need to run a sample app on both Android and iOS devices.

How do I run my app?

In React Native, you would run npm run or yarn run from the project directory.

You can run Flutter apps in a couple of ways:

  • Use the “run” option in an IDE with the Flutter and Dart plugins.
  • Use flutter run from the project’s root directory.

Your app runs on a connected device, the iOS simulator, or the Android emulator.

For more information, see the Flutter Getting Started documentation.

How do I import widgets?

In React Native, you need to import each required component.

//React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

In Flutter, to use widgets from the Material Design library, import the material.dart package. To use iOS style widgets, import the Cupertino library. To use a more basic widget set, import the Widgets library. Or, you can write your own widget library and import that.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/my_widgets.dart';

Whichever widget package you import, Dart pulls in only the widgets that are used in your app.

For more information, see the Flutter Widgets Catalog.

What is the equivalent of the React Native “Hello world!” app in Flutter?

In React Native, the HelloWorldApp class extends React.Component and implements the render method by returning a view component.

// React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Hello world!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  }
});

In Flutter, you can create an identical “Hello world!” app using the Center and Text widgets from the core widget library. The Center widget becomes the root of the widget tree and has one child, the Text widget.

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

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}

The following images show the Android and iOS UI for the basic Flutter “Hello world!” app.

Now that you’ve seen the most basic Flutter app, the next section shows how to take advantage of Flutter’s rich widget libraries to create a modern, polished app.

How do I use widgets and nest them to form a widget tree?

In Flutter, almost everything is a widget.

Widgets are the basic building blocks of an app’s user interface. You compose widgets into a hierarchy, called a widget tree. Each widget nests inside a parent widget and inherits properties from its parent. Even the application object itself is a widget. There is no separate “application” object. Instead, the root widget serves this role.

A widget can define:

  • A structural element—like a button or menu
  • A stylistic element—like a font or color scheme
  • An aspect of layout—like padding or alignment

The following example shows the “Hello world!” app using widgets from the Material library. In this example, the widget tree is nested inside the MaterialApp root widget.

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello world'),
        ),
      ),
    );
  }
}

The following images show “Hello world!” built from Material Design widgets. You get more functionality for free than in the basic “Hello world!” app.


When writing an app, you’ll use two types of widgets: StatelessWidget or StatefulWidget. A StatelessWidget is just what it sounds like—a widget with no state. A StatelessWidget is created once, and never changes its appearance. A StatefulWidget dynamically changes state based on data received, or user input.

The important difference between stateless and stateful widgets is that StatefulWidgets have a State object that stores state data and carries it over across tree rebuilds, so it’s not lost.

In simple or basic apps it’s easy to nest widgets, but as the code base gets larger and the app becomes complex, you should break deeply nested widgets into functions that return the widget or smaller classes. Creating separate functions and widgets allows you to reuse the components within the app.

How do I create reusable components?

In React Native, you would define a class to create a reusable component and then use props methods to set or return properties and values of the selected elements. In the example below, the CustomCard class is defined and then used inside a parent class.

// React Native
class CustomCard extends React.Component {
  render() {
    return (
      <View>
        <Text> Card {this.props.index} </Text>
        <Button
          title="Press"
          onPress={() => this.props.onPress(this.props.index)}
        />
      </View>
    );
  }
}

// Usage
<CustomCard onPress={this.onPress} index={item.key} />

In Flutter, define a class to create a custom widget and then reuse the widget. You can also define and call a function that returns a reusable widget as shown in the build function in the following example.

// Flutter
class CustomCard extends StatelessWidget {
  CustomCard({@required this.index, @required 
     this.onPress});

  final index;
  final Function onPress;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        children: <Widget>[
          Text('Card $index'),
          FlatButton(
            child: const Text('Press'),
            onPressed: this.onPress,
          ),
        ],
      )
    );
  }
}
    ...
// Usage
CustomCard(
  index: index,
  onPress: () { 
    print('Card $index');
  },
)
    ...

In the previous example, the constructor for the CustomCard class uses Dart’s curly brace syntax { } to indicate named optional parameters.

To require these fields, either remove the curly braces from the constructor, or add @required to the constructor.

The following screenshots show an example of the reusable CustomCard class.

Similar pages

Page structure
Terms

Flutter

Widget

StatelessWidget

State

StatefulWidget

Container