Dart and Flutter Development
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
main()function: Every Dart program starts execution in themain()function.var,final,const:varinfers type,finalis a runtime constant, andconstis a compile-time constant.- Core Data Types: The four fundamental types are
int(integers),double(decimals),String(text), andbool(true/false). - Operators: Use
+,-,*,/for arithmetic and&&(AND),||(OR),!(NOT) for logical operations. - Control Flow:
if-elsestatements make decisions, whileforandwhileloops repeat tasks. - Functions: Functions are reusable blocks of code that take inputs (parameters) and can produce an output (return value).
- Classes & Objects: A
classis a blueprint for anobject; in Flutter, almost everything, including UI elements, is an object.
Flutter Project Structure
lib/folder: This directory is where you will write 99% of your application's Dart code.main.dart: The entry point of your Flutter app, which contains themain()function that runs the app.pubspec.yaml: The project's configuration file. You use it to add third-party packages (dependencies) and include assets like images and fonts.- Platform Folders: The
android/andios/folders contain native project code for platform-specific setup. flutter create: The terminal command used to generate a new, fully configured Flutter project from scratch.
Flutter UI Basics
- Everything is a Widget: The core philosophy of Flutter. Your entire UI is composed of a hierarchy of widgets.
- Widget Tree: Widgets are nested inside one another to form a tree structure that Flutter uses to render the UI.
MaterialApp&Scaffold:MaterialAppis the root widget providing app-level features.Scaffoldprovides the standard visual layout structure (app bar, body, etc.).- Layout Widgets:
Rowarranges widgets horizontally, andColumnarranges them vertically. Container: A fundamental widget used for styling, sizing, and positioning with properties likepadding,margin, andcolor.build()method: Every widget has abuild()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
- Stateless vs. Stateful:
StatelessWidgetis for UI that never changes.StatefulWidgetis for UI that can change dynamically. StateObject: AStatefulWidgetuses a companionStateobject to hold its mutable data.setState(): The essential method called within aStateobject to notify Flutter that its internal state has changed, triggering a UI rebuild.- User Input Widgets:
ElevatedButton,TextButton, andTextFieldare common widgets for handling user interaction. - Event Handlers: Properties like
onPressedandonChangedare functions that execute in response to user actions.
Advanced Flutter UI
ListView.builder: The most efficient way to create a scrollable list, as it only builds the items that are currently visible on screen.ListTile: A pre-styled widget perfect for creating rows in aListView, often containing an icon, title, and subtitle.- Navigator: Manages a stack of 'routes' (screens).
Navigator.push()adds a new screen to the stack, andNavigator.pop()removes the current one. - Passing Data: Data can be passed to a new screen by providing it as an argument in the new screen's constructor.
- Routes: A route is an abstraction for a screen or page in a Flutter app.
Building & Deployment
- Debug vs. Release Mode: Debug mode includes tools like hot reload for rapid development. Release mode is optimized for performance and smaller app size.
- Running on a Device: You can run your app on a physical Android or iOS device connected via USB.
- App Icon & Name: These are configured in platform-specific files (
AndroidManifest.xmlfor Android,Info.plistfor iOS). flutter build apk: The command to generate a shareable Android application package (APK) file.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 namedscoreand initializes it with the value 10. - Don't confuse with: A constant (
finalorconst), 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
Textwidget 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 theStateand then callingsetState(). - 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
httppackage for making network requests, you list it underdependencies:inpubspec.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
Columnwidget is a layout widget that arranges its children in a vertical stack. - Don't confuse with: A visual widget like
TextorIcon, 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 forUserobjects. - 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.builderto display a long list of social media posts without using excessive memory. - Topic: Advanced Flutter UI
🔍 Key Comparisons
| Feature | var | final | const |
|---|---|---|---|
| Reassignment | Can 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. |
| Initialization | Can 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 Use | For 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). |
| Example | var 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
| Feature | StatelessWidget | StatefulWidget |
|---|---|---|
| Purpose | For UI that is static and does not change based on user interaction or data. | For UI that needs to change dynamically during runtime. |
| Data | Data is immutable and typically passed in through the constructor. | Holds mutable data in a separate State object. |
| Key Method | build() | createState() and build() (inside the State object). |
| Updating UI | The 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 Case | A 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 theStateclass and update it inside asetState()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, likesetState(() { _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
Columnallows its children to be as tall as they want, but aListViewtries to take up infinite vertical space, causing a render overflow error. - ✅ Instead: Wrap the
ListViewin a widget that gives it a bounded height, likeExpanded(to fill remaining space) orSizedBox(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) andconst(compile-time constant). A value from a database or API is not known when the code is compiled. - ✅ Instead: Use
finalfor variables that are assigned once but whose value isn't known until the app runs. Useconstonly 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
StatefulWidgetto hold the changing state. - Work: Define a class
CounterPagethat extendsStatefulWidgetand its corresponding_CounterPageStateclass.
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
Stateclass. - Work: Declare an integer variable
_counterand initialize it to 0.
class _CounterPageState extends State<CounterPage> {
int _counter = 0; // Our state variable
}
Step 3: Build the UI
- Reasoning: The
buildmethod describes the UI. We'll use aScaffoldfor basic layout, aColumnto stack the text and button, and aTextwidget to display the counter. - Work: Implement the
buildmethod to show the_countervalue.
@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
_counterand tells Flutter to rebuild the UI. We use aFloatingActionButtonand callsetState()in itsonPressedcallback. - Work: Add a
FloatingActionButtonto theScaffoldand implement the_incrementCountermethod.
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
Scaffoldprovides the basic structure for a screen. - Work: In your widget's
buildmethod, return aScaffoldwith anAppBarand abody.
@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:
ListViewis the standard widget for creating a scrollable list of children. - Work: Place a
ListViewwidget in thebodyof theScaffold.
body: ListView(
children: <Widget>[
// List items will go here
],
)
Step 3: Add ListTile Widgets as Children
- Reasoning:
ListTileis a pre-formatted widget designed for creating rows in a list. It has convenient properties likeleading(for an icon) andtitle(for text). - Work: Add three
ListTilewidgets to thechildrenarray of theListView.
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