Flutter Basics
Now that you've mastered Dart, it's time to build your first Flutter app! Flutter is Google's UI toolkit for crafting beautiful, natively compiled applications. In Flutter, the core philosophy is: Everything is a Widget.
Why This Topic Matters
Understanding the concept of widgets and the "Widget Tree" is the "Aha!" moment for every Flutter developer. Once you grasp how widgets compose together to form a user interface, you can build almost anything. Furthermore, distinguishing between Stateless and Stateful widgets is crucial for managing how your app's UI updates in response to user interaction or data changes.
How To Study This Chapter
Think of widgets as Lego blocks. Some blocks are just for display (Stateless), while others can change their shape or color (Stateful). As you read, visualize how widgets are nested inside each other. The "Widget Tree" is just a nested list of objects.
What is a Widget?
A widget is an immutable description of part of a user interface. It can describe structural elements (like a button or menu), stylistic elements (like a font or color scheme), or even layout aspects (like padding).
The Widget Tree
Flutter builds the UI by composing widgets into a tree structure. For example:
MaterialApp(Root)Scaffold(Screen structure)AppBar(Top bar)Center(Layout)Text(Content)
Stateless vs. Stateful Widgets
This is the most important distinction in Flutter.
Stateless Widgets
These widgets are immutable. Their properties cannot change once they are built. Use them for UI that doesn't depend on any data other than what's passed in during construction.
import 'package:flutter/material.dart';
class MyTextWidget extends StatelessWidget {
final String text;
// Constructor
MyTextWidget(this.text);
@override
Widget build(BuildContext context) {
return Text(text);
}
}
Stateful Widgets
These widgets can change over time. They maintain a State object that stores data that might change during the lifetime of the widget. When the state changes, the widget is rebuilt.
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _increment() {
setState(() {
_counter++; // This tells Flutter to rebuild the UI
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_counter'),
ElevatedButton(
onPressed: _increment,
child: Text('Increment'),
),
],
);
}
}
The build() Method
The build method is where you describe what your widget should look like. Flutter calls this method whenever the widget needs to be rendered or updated. It must return a Widget.
Basic Project Structure
When you create a new Flutter project, you'll see a lib/main.dart file. This is the entry point of your app.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello Flutter!'),
),
),
),
);
}
In the next chapter, we'll explore how to arrange these widgets into complex and beautiful layouts!