No history yet

Study Guide

📖 Core Concepts

Dart Fundamentals Dart is an object-oriented language with a C-style syntax used to define the logic, data, and structure of Flutter applications.

Flutter Project Structure A Flutter project organizes code in the lib folder and manages dependencies and assets through the pubspec.yaml file.

Flutter UI Basics Flutter's UI is built from a tree of immutable widgets, like Column and Row, which are arranged to create visual layouts.

Flutter Interactivity App interactivity is managed by changing State in a StatefulWidget and responding to user input events like button presses.

Advanced Flutter UI Dynamic content is displayed in scrollable lists like ListView, and navigation between screens is handled by the Navigator widget.

Building & Deployment Apps run in debug mode for development and are compiled into release mode to create a final APK or iOS app bundle for distribution.

📌 Must Remember

Dart Fundamentals

  1. main() function: Every Dart program starts execution in the main() function.
  2. var, final, const: var infers type, final is a runtime constant, and const is a compile-time constant.
  3. Core Data Types: The four fundamental types are int (integers), double (decimals), String (text), and bool (true/false).
  4. Operators: Use +, -, *, / for arithmetic and && (AND), || (OR), ! (NOT) for logical operations.
  5. Control Flow: if-else statements make decisions, while for and while loops repeat tasks.
  6. Functions: Functions are reusable blocks of code that take inputs (parameters) and can produce an output (return value).
  7. Classes & Objects: A class is a blueprint for an object; in Flutter, almost everything, including UI elements, is an object.

Flutter Project Structure

  1. lib/ folder: This directory is where you will write 99% of your application's Dart code.
  2. main.dart: The entry point of your Flutter app, which contains the main() function that runs the app.
  3. pubspec.yaml: The project's configuration file. You use it to add third-party packages (dependencies) and include assets like images and fonts.
  4. Platform Folders: The android/ and ios/ folders contain native project code for platform-specific setup.
  5. flutter create: The terminal command used to generate a new, fully configured Flutter project from scratch.

Flutter UI Basics

  1. Everything is a Widget: The core philosophy of Flutter. Your entire UI is composed of a hierarchy of widgets.
  2. Widget Tree: Widgets are nested inside one another to form a tree structure that Flutter uses to render the UI.
  3. MaterialApp & Scaffold: MaterialApp is the root widget providing app-level features. Scaffold provides the standard visual layout structure (app bar, body, etc.).
  4. Layout Widgets: Row arranges widgets horizontally, and Column arranges them vertically.
  5. Container: A fundamental widget used for styling, sizing, and positioning with properties like padding, margin, and color.
  6. build() method: Every widget has a build() method that returns the widget(s) it should render on the screen. Flutter calls this method when it needs to draw the UI.

Flutter Interactivity

  1. Stateless vs. Stateful: StatelessWidget is for UI that never changes. StatefulWidget is for UI that can change dynamically.
  2. State Object: A StatefulWidget uses a companion State object to hold its mutable data.
  3. setState(): The essential method called within a State object to notify Flutter that its internal state has changed, triggering a UI rebuild.
  4. User Input Widgets: ElevatedButton, TextButton, and TextField are common widgets for handling user interaction.
  5. Event Handlers: Properties like onPressed and onChanged are functions that execute in response to user actions.

Advanced Flutter UI

  1. ListView.builder: The most efficient way to create a scrollable list, as it only builds the items that are currently visible on screen.
  2. ListTile: A pre-styled widget perfect for creating rows in a ListView, often containing an icon, title, and subtitle.
  3. Navigator: Manages a stack of 'routes' (screens). Navigator.push() adds a new screen to the stack, and Navigator.pop() removes the current one.
  4. Passing Data: Data can be passed to a new screen by providing it as an argument in the new screen's constructor.
  5. Routes: A route is an abstraction for a screen or page in a Flutter app.

Building & Deployment

  1. Debug vs. Release Mode: Debug mode includes tools like hot reload for rapid development. Release mode is optimized for performance and smaller app size.
  2. Running on a Device: You can run your app on a physical Android or iOS device connected via USB.
  3. App Icon & Name: These are configured in platform-specific files (AndroidManifest.xml for Android, Info.plist for iOS).
  4. flutter build apk: The command to generate a shareable Android application package (APK) file.
  5. flutter build ipa: The command to generate an app archive for iOS distribution.

📚 Key Terms

Variable: A named container in your code that stores a piece of data which can be referenced and modified.

  • Used in context: var score = 10; declares a variable named score and initializes it with the value 10.
  • Don't confuse with: A constant (final or const), which cannot be reassigned after its initial value is set.
  • Topic: Dart Fundamentals

Widget: The basic building block of a Flutter UI. Every element on the screen, from a button to the padding around it, is a widget.

  • Used in context: You use a Text widget to display a string on the screen: Text('Hello, World!');.
  • Topic: Flutter UI Basics

State: Any data that can change over time and should affect the UI. For example, the current value of a counter or whether a checkbox is ticked.

  • Used in context: In a StatefulWidget, you update the UI by changing the State and then calling setState().
  • Topic: Flutter Interactivity

pubspec.yaml: The project's manifest file that defines its metadata, dependencies (external packages), and asset locations (images, fonts).

  • Used in context: To add the http package for making network requests, you list it under dependencies: in pubspec.yaml.
  • Topic: Flutter Project Structure

Function: A self-contained block of code that performs a specific task and can be called (executed) from other parts of the program.

  • Used in context: void printGreeting(String name) { print('Hello, $name'); } defines a function that prints a personalized greeting.
  • Topic: Dart Fundamentals

setState(): A method available in a StatefulWidget's State class that tells the Flutter framework that the object's internal state has changed, and the UI should be redrawn.

  • Used in context: To increment a counter, you'd call setState(() { _counter++; });.
  • Topic: Flutter Interactivity

Layout Widget: A widget whose primary purpose is to control the position, size, and arrangement of its child widgets.

  • Used in context: The Column widget is a layout widget that arranges its children in a vertical stack.
  • Don't confuse with: A visual widget like Text or Icon, which displays something directly.
  • Topic: Flutter UI Basics

Navigator: The widget that manages a stack of screen routes. It allows you to 'push' new screens onto the view and 'pop' them off to go back.

  • Used in context: To go to a settings screen, you would call Navigator.push(context, MaterialPageRoute(builder: (context) => SettingsScreen()));.
  • Topic: Advanced Flutter UI

Class: A blueprint for creating objects. It defines a set of properties (data) and methods (functions) that the created objects will have.

  • Used in context: class User { String name; String email; } defines a blueprint for User objects.
  • Topic: Dart Fundamentals

ListView.builder: A constructor for ListView that builds its children on demand, making it highly efficient for long or infinite lists.

  • Used in context: You use ListView.builder to display a long list of social media posts without using excessive memory.
  • Topic: Advanced Flutter UI

🔍 Key Comparisons

Featurevarfinalconst
ReassignmentCan be reassigned to a new value (of the same type).Cannot be reassigned. Once set, its value is final.Cannot be reassigned. It's a compile-time constant.
InitializationCan be declared without an initial value.Can be initialized at runtime (e.g., from an API call).Must be initialized with a constant value at compile-time.
When to UseFor local variables that need to change.For variables you only set once (e.g., instance properties).For values known before the app runs (e.g., colors, padding values).
Examplevar count = 5; count = 6;final name = 'Dart';const appVersion = '1.0.0';

Memory trick: var is variable. final is final. const is constant at compile time.

Topic: Dart Fundamentals


FeatureStatelessWidgetStatefulWidget
PurposeFor UI that is static and does not change based on user interaction or data.For UI that needs to change dynamically during runtime.
DataData is immutable and typically passed in through the constructor.Holds mutable data in a separate State object.
Key Methodbuild()createState() and build() (inside the State object).
Updating UIThe widget is completely rebuilt with new data from its parent.The setState() method is called to trigger a rebuild of its part of the widget tree.
Example Use CaseA logo, an icon, a static text label.A counter, a checkbox, a form with text fields, a loading spinner.

Memory trick: Stateless has less complexity (no State object). Stateful is full of changing data.

Topic: Flutter Interactivity

⚠️ Common Mistakes

MISTAKE: Modifying a variable inside a StatelessWidget and expecting the UI to update.

  • Why it happens: Beginners assume changing a variable's value will automatically redraw the screen. StatelessWidgets are immutable and have no mechanism to track changes.
  • Instead: If your UI needs to change, convert the widget to a StatefulWidget. Store the variable in the State class and update it inside a setState() call.
  • Topic: Flutter Interactivity

MISTAKE: Forgetting to call setState() after updating a variable in a StatefulWidget.

  • Why it happens: The variable's value changes in memory, but Flutter's framework doesn't know it needs to rebuild the UI to reflect this change.
  • Instead: Always wrap state-changing assignments in a setState() callback, like setState(() { _myValue = 'new value'; });. This is the signal for Flutter to repaint.
  • Topic: Flutter Interactivity

MISTAKE: Placing an infinitely tall widget (like a ListView) inside a Column without wrapping it.

  • Why it happens: A Column allows its children to be as tall as they want, but a ListView tries to take up infinite vertical space, causing a render overflow error.
  • Instead: Wrap the ListView in a widget that gives it a bounded height, like Expanded (to fill remaining space) or SizedBox (to give it a fixed height).
  • Topic: Flutter UI Basics

MISTAKE: Declaring a variable with const when its value is determined at runtime.

  • Why it happens: Confusion between final (runtime constant) and const (compile-time constant). A value from a database or API is not known when the code is compiled.
  • Instead: Use final for variables that are assigned once but whose value isn't known until the app runs. Use const only for true, hard-coded constants.
  • Topic: Dart Fundamentals

📝 Worked Examples

Example: Creating a Simple Counter App

Problem: Build a screen with a number displayed and a button. When the button is pressed, the number should increase by one.

Solution:

Step 1: Create a StatefulWidget

  • Reasoning: The UI needs to change (the number increases), so we must use a StatefulWidget to hold the changing state.
  • Work: Define a class CounterPage that extends StatefulWidget and its corresponding _CounterPageState class.
class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  // State will go here
}

Step 2: Define the State Variable

  • Reasoning: We need a variable to hold the current count. It must be inside the State class.
  • Work: Declare an integer variable _counter and initialize it to 0.
class _CounterPageState extends State<CounterPage> {
  int _counter = 0; // Our state variable
}

Step 3: Build the UI

  • Reasoning: The build method describes the UI. We'll use a Scaffold for basic layout, a Column to stack the text and button, and a Text widget to display the counter.
  • Work: Implement the build method to show the _counter value.
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Counter App')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('You have pushed the button this many times:'),
          Text(
            '$_counter', // Display the counter value
            style: Theme.of(context).textTheme.headline4,
          ),
        ],
      ),
    ),
  );
}

Step 4: Add the Button and setState() Logic

  • Reasoning: We need a button that, when pressed, increments the _counter and tells Flutter to rebuild the UI. We use a FloatingActionButton and call setState() in its onPressed callback.
  • Work: Add a FloatingActionButton to the Scaffold and implement the _incrementCounter method.
void _incrementCounter() {
  setState(() {
    // This call to setState tells the framework that our state has changed,
    // and causes it to rerun the build method to display the updated value.
    _counter++;
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    // ... (appBar and body from above)
    floatingActionButton: FloatingActionButton(
      onPressed: _incrementCounter, // Call our method on press
      tooltip: 'Increment',
      child: Icon(Icons.add),
    ),
  );
}

Answer: You now have a complete, functioning counter application. The number on the screen will increase each time the '+' button is pressed.

⚠️ Common pitfall: Calling _counter++ outside of the setState() callback. The variable would update, but the screen would not.

Topic: Flutter Interactivity


Example: Building a Static List

Problem: Display a vertical, scrollable list of three items, each with an icon and text.

Solution:

Step 1: Set up the Scaffold

  • Reasoning: A Scaffold provides the basic structure for a screen.
  • Work: In your widget's build method, return a Scaffold with an AppBar and a body.
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('My List')),
    body: // List will go here
  );
}

Step 2: Use a ListView Widget

  • Reasoning: ListView is the standard widget for creating a scrollable list of children.
  • Work: Place a ListView widget in the body of the Scaffold.
body: ListView(
  children: <Widget>[
    // List items will go here
  ],
)

Step 3: Add ListTile Widgets as Children

  • Reasoning: ListTile is a pre-formatted widget designed for creating rows in a list. It has convenient properties like leading (for an icon) and title (for text).
  • Work: Add three ListTile widgets to the children array of the ListView.
body: ListView(
  children: <Widget>[
    ListTile(
      leading: Icon(Icons.map),
      title: Text('Map'),
    ),
    ListTile(
      leading: Icon(Icons.photo_album),
      title: Text('Album'),
    ),
    ListTile(
      leading: Icon(Icons.phone),
      title: Text('Phone'),
    ),
  ],
)

Answer: The screen now displays a clean, scrollable list with three rows, each containing an icon and a title.

⚠️ Common pitfall: Using a Column instead of a ListView for a long list of items. A Column renders all its children at once, which can cause performance issues, whereas a ListView is optimized for scrolling.

Topic: Advanced Flutter UI