Dart Tutorial

Dart Tutorial Single-Page Application Architecture Dart Features Dart Installation Guide Dart Basic Program Dart Syntax Dart Keywords Dart Variables Dart Comments Dart Standard Input Output Dart Important Concepts

Data Types

Built-in Data Types Numbers Strings Booleans Lists Sets Maps Runes and Graphemes Symbols Enumerations Constants Queues

Other data types

Objects Future and stream Iterable Miscellaneous types

OPERATORS

Precedence and associativity Arithmetic operators Equality and Relational operators Type Test Operators Assignment Operators Logical Operators Bitwise and Shift Operators Miscellaneous operators

Control Flow Statements

Introduction If statement If-else statement If-else-if statement Loops Switch and case Dart Break And Continue Assert In Dart

FUNCTIONS

Dart function Types of Functions Anonymous function main( ) function Lexical scope and closure Recursion Common Collection Methods

Object Oriented Concepts

Dart Object-Oriented Concepts Dart Classes Dart Constructors Dart This Keyword Dart Super Keyword Static Members Method Overriding Dart Interfaces Inheritance Dart Abstract Classes Dart Builder Classes Dart Callable Classes

Dart Type System

Dart Type System Dart Soundness Dart Type Inference

MISCELLANEOUS

Dart Isolates Dart Typedef Dart Metadata Dart Packages Dart Generics Dart Generators Dart Concurrency Dart Unit Testing Dart Html Dom Dart URIs Dart Extends, With and Implements Keywords Dart Optional Parameters Rust Vs Dart C++ vs Dart Golang Vs Dart Dart Basics Exception Handling

Builder Classes in Dart

Before understanding builder classes, let us understand about Flutter that makes the best use of the builder classes. Flutter is actually not a programming language, it is a software development kit (SDK) that has some in-built macros, customizable and read-to-use widgets as well as libraries and tools that can be deployed while creating cross-platform mobile applications.

In Flutter, to create a new widget we use a ' build ' widget associated with that particular widget and the framework passes the BuildContext parameter to it.

' Build ' Widget ( BuildContext context ) :

In Flutter, other than the build widget there isn't any other widget that needs the context parameter in their constructors or functions. Therefore, the context parameter has to be passed through the build widget only, otherwise there will be more than one call to the build function. To accomplish this, we make use of the ' Builder ' class that creates the child and returns it. This Builder class passes a comtext to the child. This child acts as a custom build function.

Builder class constructor :

Builder( { key key, @required WidgetBuilder builder } ) // 

this creates a widget that delegates its build to a callback.

It is mandatory to not keep the argument null.

Builder class Methods

The various methods associated with the builder class are :

  1. build( BuildContext context ) -> Widget
  2. createElement( ) -> StatelessElement
  3. debugDescribeChildren( ) -> List< DiagnosticsNode >
  4. debugFillProperties( DiagnosticPropertiesBuilder properties ) -> void
  5. noSuchMethod( Invocation invocation ) -> dynamic
  6. toString( { DiagnosticLevel minLevel : DiagnosticLevel.info } ) -> String
  7. toStringDeep( { String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug } ) -> String
  8. toStringShallow( { String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug } ) -> String
  9. toStringShort( ) -> String

Let us consider the following example in Dart that explains the concept of the Builder class. To increase the understandability of this concept, we will be making a simple mobile application. This will app will only have a main page containing scaffold with an AppBar and a button which when tapped display a message.

Example :

import ' package:flutter/material.dart ' ;
void main( ) 
{
  runApp( MyApp( ) ) ;
}
class MyApp extends StatelessWidget 
{
// This widget is the root of your application.
  @override
  Widget build( BuildContext context ) 
{
    return MaterialApp (
      title : ' Builder App Demo ' ,
      debugShowCheckedModeBanner : false ,
      theme: ThemeData (
        primarySwatch : Colors.green ,
      ) ,
      home : Home( ) ,
    ) ;
  }
}
class Home extends StatelessWidget 
{
  @override
  Widget build( BuildContext context ) 
{
    return Scaffold (
      // appbar
      appBar : AppBar (
        title : Text( ' Assert Tutorial ' ) ,
      ) ,
      // detect gesture
      body : Center (
        child : GestureDetector (
          onTap : ( ) {
            Scaffold.of( context ).showSnackBar (
              new SnackBar (
                content : new Text( ' This is an assert Tutorial ' ) ,
              ) ,
            ) ;
          } ,
          // box styling
          Child : Container (
            margin : EdgeInsets.all( 18 ) ,
            height : 40 ,
            decoration : BoxDecoration (
              color : Colors.blueAccent ,
              borderRadius : BorderRadius.circular( 8 ) ,
            ) ,
            child : Center (
              child : Text (
                ' CLICK HERE ' ,
                style :
                TextStyle( fontWeight : FontWeight.bold, color : Colors.white ) ,
              ) ,
            ) ,
          ) ,
        ) ,
      ) ,
    ) ;
  }
}

Output :

However, this code resulted in an error because the same context is being passed to the Scaffold and the SnackBar widget. The content being passed as a parameter to the Scaffold does not actually belong to it. So, the app gives the following error.

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Scaffold.of() called with a context that does not contain a Scaffold.
No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.

However, on tapping the button ‘ CLICK HERE ’ the following output is being displayed :

On tapping the button one time, following output was displayed :

Handler: "onTap"
Recognizer: TapGestureRecognizer#3ed06
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(826.4, 387.2)
finalLocalPosition: Offset(826.4, 38.4)
button: 1
sent tap down
====================================================================================================

We have tried to resolve the error of the above code in the following program. Consider another example :

import ' package:flutter/material.dart ' ;
void main( ) {
  runApp( MyApp( ) ) ;
}
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build( BuildContext context ) {
    return MaterialApp (
      title : ' Builder Demo ' ,
      debugShowCheckedModeBanner : false ,
      theme : ThemeData (
        primarySwatch : Colors.green ,
      ) ,
      home : Home( ) ,
    ) ;
  }
}
class Home extends StatelessWidget {
  @override
  Widget build( BuildContext context ) {
    return Scaffold (
      // appbar
      appBar : AppBar (
        title : Text( ' Assert Statement ' ) ,
      ) ,
      // detect gesture
      body : Center (
        child : Builder ( builder : ( BuildContext context ) {
          return GestureDetector (
            onTap : ( ) {
              Scaffold.of( context ).showSnackBar (
                new SnackBar (
                  content : new Text( ' This is the Dart Tutorial ' ) ,
                ) ,
              ) ;
            } ,
            child : Container (
              margin: EdgeInsets.all( 18 ) ,
              height : 40 ,
              decoration : BoxDecoration (
                color : Colors.blueGrey ,
                borderRadius : BorderRadius.circular( 8 ) ,
              ) ,
              child : Center (
                child : Text (
                  ' CLICK ME ' ,
                  style : TextStyle (
                      fontWeight : FontWeight.bold, color : Colors.white ) ,
                ) ,
              ) ,
            ) ,
          ) ;
        } ) ,
      ) ,
    ) ;
  } }

Output on Console :

Launching lib\main.dart on Edge in debug mode...
Waiting for connection from debug service on Edge...
This app is linked to the debug service: ws://127.0.0.1:58278/aWUVHjHPR3o=/ws
Debug service listening on ws://127.0.0.1:58278/aWUVHjHPR3o=/ws
 Running with sound null safety 
Debug service listening on ws://127.0.0.1:58278/aWUVHjHPR3o=/ws

Output on the simulator web app:

Builder Classes in Dart

Some of its properties are :

  1. Builder -> WidgetBuilder // called to obtain the child widget
  2. hashCode -> int // obtains the hash code for the object it is invoked for
  3. key -> Key? // controls the replacing of one widget by the other
  4. runtimeType -> Type // represents the object of the runtime type