Write your get-go Palpitate app, part 1

ane. Introduction

Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a unmarried codebase. Flutter works with existing lawmaking, is used by developers and organizations effectually the world, and is gratuitous and open source.

In this codelab, you'll create a simple mobile Flutter app. If you lot're familiar with object-oriented code and basic programming concepts—such as variables, loops, and conditionals—and so you can complete the codelab. You don't need previous experience with Dart, mobile, desktop, or web programming.

What y'all'll learn in role 1

  • How to write a Flutter app that looks natural on iOS, Android, desktop (Windows, for case) and the spider web
  • Basic construction of a Flutter app
  • Finding and using packages to extend functionality
  • Using hot reload for a quicker development cycle
  • How to implement a stateful widget
  • How to create an infinite, lazily loaded list

In function two of this codelab, yous'll add interactivity, modify the app's theme, and add the ability to navigate to a new folio (called a route in Flutter).

What yous'll build in part 1

You lot'll implement a unproblematic app that generates proposed names for a startup company. The user can select and unselect names, saving the best ones. The code lazily generates ten names at a fourth dimension. Every bit the user scrolls, more than names are generated. At that place is no limit to how far a user tin can roll.

The following animated GIF shows how the app works at the completion of part:

6556f8b61acd6a89.gif

What would you lot similar to acquire from this codelab?

I'm new to the topic, and I want a good overview. I know something about this topic, but I want a refresher. I'm looking for instance code to use in my projection. I'one thousand looking for an explanation of something specific.

ii. Set up up your Flutter environment

You need ii pieces of software to complete this lab—the Flutter SDK and an editor. (The codelab assumes that you're using Android Studio, but y'all can apply your preferred editor.)

You can run the codelab by using any of the following devices:

  • A physical Android or iOS device connected to your computer and prepare to developer way
  • The iOS simulator (requires installing Xcode tools)
  • The Android Emulator (requires setup in Android Studio)
  • A browser (Chrome is required for debugging)
  • As a Windows, Linux, or macOS desktop application

3. Create the starter Flutter app

b2f84ff91b0e1396.pngCreate a simple, templated Palpitate app. Create a Flutter projection called startup_namer as follows.

$ flutter create startup_namer $ cd startup_namer                      

You'll more often than not edit lib/main.sprint , where the Dart lawmaking lives.

b2f84ff91b0e1396.png Replace the contents of lib/main.dart . Delete all of the code from lib/main.dart and replace it with the following code, which displays "Hi Earth" in the center of the screen.

                        import 'bundle:flutter/fabric.dart';  void main() {   runApp(const MyApp()); }  class MyApp extends StatelessWidget {   const MyApp({Fundamental? primal}) : super(key: primal);    @override   Widget build(BuildContext context) {     return MaterialApp(       title: 'Welcome to Flutter',       home: Scaffold(         appBar: AppBar(           title: const Text('Welcome to Flutter'),         ),         body: const Center(           child: Text('Hello Earth'),         ),       ),     );   } }                                              

b2f84ff91b0e1396.png Run the app. Y'all should see either Android, iOS, Windows, Linux, macOS, or web output, depending on your device.

Windows

iOS

cf1e10b838bf60ee.png Observations

  • This example creates a Textile app. Material is a visual-design language that's standard on mobile and the spider web. Flutter offers a rich set of Material widgets.
  • The app extends StatelessWidget, which makes the app itself a widget. In Flutter, almost everything is a widget, including alignment, padding, and layout.
  • The Scaffold widget, from the Material library, provides a default app bar, a title, and a body property that holds the widget tree for the home screen. The widget subtree can be quite complex.
  • A widget'due south main job is to provide a build method that describes how to display the widget in terms of other, lower-level widgets.
  • The torso for this instance consists of a Center widget containing a Text child widget. The Eye widget aligns its widget subtree to the middle of the screen.

iv. Employ an external package

In this pace, you'll start using an open-source package named english_words , which contains a few thousand of the near-used English language words, plus some utility functions.

You can find the english_words package, too as many other open-source packages, at pub.dev.

b2f84ff91b0e1396.png Add the english_words parcel every bit a dependency of this app:

$ flutter pub add together english_words Resolving dependencies...   async 2.8.1 (2.eight.2 available)   characters ane.1.0 (1.ii.0 available) + english_words 4.0.0   matcher 0.12.10 (0.12.11 available)   test_api 0.iv.2 (0.four.5 bachelor)   vector_math 2.one.0 (two.ane.1 bachelor) Changed 1 dependency!                      

b2f84ff91b0e1396.png In lib/main.dart , import the new packet:

                        import 'parcel:english_words/english_words.dart';  // Add this line. import 'parcel:flutter/textile.sprint';                                              

As you lot blazon, Android Studio gives you suggestions for libraries to import. Information technology then renders the import string in gray, letting you know that the imported library is unused (so far).

Next, you'll use the english_words package to generate the text instead of using "Hullo Globe".

b2f84ff91b0e1396.pngMake the following changes:

                        import 'package:english_words/english_words.sprint'; import 'package:palpitate/material.dart';  void primary() {   runApp(const MyApp()); }  class MyApp extends StatelessWidget {   const MyApp({Cardinal? central}) : super(key: key);    @override   Widget build(BuildContext context) {     last wordPair = WordPair.random(); // Add together this line.     return MaterialApp(       title: 'Welcome to Flutter',       habitation: Scaffold(         appBar: AppBar(           title: const Text('Welcome to Flutter'),         ),         body: Middle(                          // Drop the const, and           //child: Text('Hullo World'),        // Replace this text...           child: Text(wordPair.asPascalCase),  // With this text.         ),       ),     );   } }                                              

b2f84ff91b0e1396.png If the app is running, hot reload e11f6ccd1560a28b.png to update the running app. (From the control line, you tin can enter r to hot reload.) Each fourth dimension you click hot reload or salve the project, you should run into a different word pair, called at random, in the running app. That's because the word pairing is generated within the build method, which runs each time the MaterialApp requires rendering, or when toggling the Platform in the Palpitate Inspector.

Windows

iOS

Bug?

If your app isn't running correctly, look for typos. If needed, utilise the lawmaking at the following links to get dorsum on rails.

  • pubspec.yaml
  • lib/main.sprint

5. Add together a stateful widget

Stateless widgets are immutable, meaning that their properties can't change—all values are final.

Countryful widgets maintain country that might change during the lifetime of the widget. Implementing a stateful widget requires at least two classes, a StatefulWidget that creates an instance of a Country class. The StatefulWidget object is, itself, immutable and can be thrown away and regenerated, but the State object persists over the lifetime of the widget.

In this pace, you'll add a stateful widget, RandomWords, which creates its Country class, _RandomWordsState. You'll so apply RandomWords as a child inside the existing MyApp stateless widget.

b2f84ff91b0e1396.png Create boilerplate code for a stateful widget.

Information technology can get anywhere in the file outside of MyApp, but the solution places information technology at the bottom of the file. In lib/principal.dart, position your cursor after all of the code, enter Return a couple times to start on a fresh line. In your IDE, start typing stful. The editor asks if yous want to create a Stateful widget. Press Return to have. The boilerplate lawmaking for two classes appears, and the cursor is positioned for yous to enter the name of your stateless widget.

b2f84ff91b0e1396.png Enter RandomWords as the name of your widget.

As you lot tin can see in the code below, the RandomWords widget does little else beside creating its Country class.

Once you've entered RandomWords as the name of the stateful widget, the IDE automatically updates the accompanying Country class, naming information technology _RandomWordsState. By default, the name of the Country class is prefixed with an underscore. Prefixing an identifier with an underscore enforces privacy in the Sprint language and is a recommended best practice for Land objects.

The IDE also automatically updates the state form to extend State<RandomWords>, indicating that you're using a generic Country class specialized for utilise with RandomWords. Most of the app'south logic resides here⁠—information technology maintains the country for the RandomWords widget. This class saves the list of generated give-and-take pairs, which grows infinitely as the user scrolls and, in role two of this lab, favorites word pairs as the user adds or removes them from the list by toggling the middle icon.

Both classes now look as follows:

                        class RandomWords extends StatefulWidget {   @override   _RandomWordsState createState() => _RandomWordsState(); }  class _RandomWordsState extends State<RandomWords> {   @override   Widget build(BuildContext context) {     return Container();   } }                                              

b2f84ff91b0e1396.png Update the build() method in _RandomWordsState.

Replace render Container(); with the following ii lines:

                        grade _RandomWordsState extends Country<RandomWords> {   @override                                     Widget build(BuildContext context) {     final wordPair = WordPair.random();      // NEW     return Text(wordPair.asPascalCase);      // NEW   }                                          }                                              

b2f84ff91b0e1396.png Remove the word-generation code from MyApp by making the following changes:

                        class MyApp extends StatelessWidget {   @override   Widget build(BuildContext context) {     final wordPair = WordPair.random();  // DELETE      render MaterialApp(       title: 'Welcome to Palpitate',       dwelling house: Scaffold(         appBar: AppBar(           title: Text('Welcome to Flutter'),         ),         body: const Center(                     // Add the const           //child: Text(wordPair.asPascalCase), // Supplant with...            child: RandomWords(),                 // ...this line         ),       ),     );   } }                                              

b2f84ff91b0e1396.png Hot reload the app. The app should behave every bit earlier, displaying a word pairing each fourth dimension you hot reload or relieve the app.

Problems?

If your app isn't running correctly, you tin use the code at the post-obit link to get dorsum on track.

  • lib/main.dart

6. Create an infinite scrolling ListView

In this footstep, you'll expand _RandomWordsState to generate and display a listing of word pairings. As the user scrolls, the list (displayed in a ListView widget) grows infinitely. The builder factory constructor in ListView allows y'all to lazily build a list view on demand.

b2f84ff91b0e1396.png Add some state variables to the _RandomWordsState grade.

Add a _suggestions list for saving suggested word pairings. Also, add a _biggerFont variable for making the font size larger.

                        class _RandomWordsState extends State<RandomWords> {   last _suggestions = <WordPair>[];                 // NEW   last _biggerFont = const TextStyle(fontSize: 18); // NEW   ... }                                              

Next, you'll add together a _buildSuggestions() part to the _RandomWordsState class. This method builds the ListView that displays the suggested word pairing.

The ListView class provides a architect belongings, itemBuilder, that'due south a manufactory builder and callback part specified every bit an anonymous function. 2 parameters are passed to the role—the BuildContext and the row index, i. The index begins at 0 and increments each time the function is called, once for every suggested discussion pairing. This model allows the suggestion list to continue growing every bit the user scrolls.

b2f84ff91b0e1396.png Add the unabridged _buildSuggestions function.

In the _RandomWordsState class, add the following office, deleting the comments, if you prefer:

                        Widget _buildSuggestions() {   return ListView.builder(     padding: const EdgeInsets.all(xvi),     // The itemBuilder callback is called once per suggested     // word pairing, and places each suggestion into a ListTile     // row. For even rows, the function adds a ListTile row for     // the discussion pairing. For odd rows, the role adds a     // Divider widget to visually divide the entries. Note that     // the divider may be difficult to see on smaller devices.     itemBuilder: (context, i) {       // Add a one-pixel-high divider widget before each row       // in the ListView.       if (i.isOdd) {         return const Divider();       }        // The syntax "i ~/ two" divides i past ii and returns an       // integer event.       // For example: one, 2, three, four, 5 becomes 0, 1, 1, 2, 2.       // This calculates the actual number of word pairings       // in the ListView,minus the divider widgets.       final index = i ~/ 2;       // If y'all've reached the end of the available word       // pairings...       if (index >= _suggestions.length) {         // ...then generate x more and add them to the         // suggestions listing.         _suggestions.addAll(generateWordPairs().accept(ten));       }       return _buildRow(_suggestions[index]);     },   ); }                                              

The _buildSuggestions role calls _buildRow once per give-and-take pair. That function displays each new pair in a ListTile, which allows you to make the rows more than attractive in part ii.

b2f84ff91b0e1396.png Add a _buildRow function to _RandomWordsState:

                                                  Widget _buildRow(WordPair pair) {     render ListTile(       title: Text(         pair.asPascalCase,         fashion: _biggerFont,       ),     );   }                                              

b2f84ff91b0e1396.png Update the build method for _RandomWordsState.

Change it to use _buildSuggestions(), rather than directly calling the word-generation library. ( Scaffold implements the basic Textile Pattern visual layout.)

                                                  @override   Widget build(BuildContext context) {     //final wordPair = WordPair.random(); // Delete these...      //return Text(wordPair.asPascalCase); // ... two lines.      return Scaffold (                     // Add from here...        appBar: AppBar(         championship: const Text('Startup Proper noun Generator'),       ),       torso: _buildSuggestions(),     );                                      // ... to here.   }                                              

b2f84ff91b0e1396.png Update the build method for MyApp, irresolute the title, removing the AppBar, and changing the home property to a RandomWords widget.

                                                  @override   Widget build(BuildContext context) {     return const MaterialApp(       title: 'Startup Proper name Generator',       dwelling: RandomWords(),     );   }                                              

b2f84ff91b0e1396.png Restart the app. Y'all should see a list of discussion pairings no matter how far y'all scroll.

Windows

iOS

Problems?

If your app isn't running correctly, yous can utilize the lawmaking at the following link to get back on runway.

  • lib/chief.dart

vii. Next steps

Congratulations!

You have completed part 1 of this codelab! If you lot'd like to extend this app, proceed to office 2, where yous will change the app as follows:

  • Add interactivity.
  • Add the ability to navigate to a new route.
  • Modify the theme color.

When office 2 is completed, the app volition look like this:

7fcab088cd22cff7.gif

Other adjacent steps

Learn more than near the Palpitate SDK with the following resources:

  • Layouts in Flutter
  • Add interactivity tutorial
  • Introduction to widgets
  • Palpitate for Android developers
  • Palpitate for React Native developers
  • Flutter for web developers
  • Palpitate YouTube aqueduct

Other resources include the following:

  • From Coffee to Dart codelab
  • Palpitate cookbook
  • Bootstrap into Dart: learn more than near the language

Too, connect with the Flutter community!