Flutter to framework UI od Google do natywnych aplikacji wieloplatformowych. Według Flutter Docs (2025), Flutter jest używany w ponad 500 000 aplikacji w Google Play. Zrozumienie Widget, StatefulWidget, BuildContext i drzewa renderowania to podstawa programowania we Flutterze.
Najważniejsze
Widget — deklaratywny opis części UI. Wszystko we Flutterze jest Widgetem: od przycisku do samej aplikacji. Widget to konfiguracja (nie samo UI). StatelessWidget — niezmienny Widget. build() jest wywoływany raz. Nie ma stanu. Używany do statycznej treści. StatefulWidget — zmienny Widget. Ma obiekt State, który może się zmieniać. setState() — wyzwala przebudowę. State — zmienny obiekt powiązany z StatefulWidget. Zawiera dane, które mogą się zmieniać.
StatelessWidget — build() jest wywoływany raz. Nadaje się do nagłówków, ikon, statycznych tekstów. StatefulWidget — build() jest wywoływany za każdym razem, gdy wywołano setState(). Nadaje się do formularzy, list ze zmianami, timerów. InheritedWidget — przekazywanie danych w dół bez jawnego przekazywania przez konstruktory. Theme, MediaQuery, Navigator — InheritedWidgets. BuildContext — pozycja Widgeta w drzewie. context.of<T>, context.watch<T>, context.select<T,R> — dostęp do InheritedWidget.
// Przykład Flutter Widget: StatefulWidget z setState
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Counter')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have pushed the button:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
),
);
}
}Widget — konfiguracja. StatelessWidget — niezmienny. StatefulWidget — zmienny z setState(). IT Sectr zaleca zaczynanie od StatelessWidget i przechodzenie na StatefulWidget tylko gdy potrzebny jest stan.
Flutter używa trzech drzew do wydajnego renderowania. Widget Tree — drzewo konfiguracji. Widgety są tworzone często (każdy build), lekkie. Element Tree — drzewo elementów. Jeden element na Widget (jeśli typ się nie zmienia). Element — most między Widgetem a RenderObject. RenderObject Tree — drzewo renderowania. Odpowiada za rozmiary, pozycje, rysowanie. RenderObject — ciężki, tworzony rzadko. Flutter porównuje Widget Tree i aktualizuje Element Tree, co wyzwala aktualizację RenderObject Tree.
Key — identyfikator Widgeta w Element Tree. ValueKey, ObjectKey, UniqueKey, PageStorageKey. Keys pozwalają Flutterowi dopasowywać stare i nowe Widgety podczas przebudowy. Bez Keys Flutter dopasowuje według typu Widgeta i pozycji. GlobalKey — dostęp do State z innego Widgeta. Używane do: złożonych formularzy, animacji, dostępu do State w testach. IT Sectr zaleca używanie Keys dla list (List.generate) i unikanie GlobalKey, chyba że to konieczne.
Expanded — Widget wypełniający dostępne miejsce w Row/Column/Flex. Flexible — nie wymusza wypełnienia (może być mniejszy). MediaQuery — InheritedWidget z informacjami o urządzeniu: rozmiar ekranu, orientacja, platforma, współczynnik skali tekstu. Theme/ThemeData — scentralizowany motyw. Theme.of(context) — dostęp. MaterialApp — główny Widget do konfiguracji routingu, motywów, ustawień regionalnych. Scaffold — podstawowy układ z AppBar, Drawer, BottomNavigationBar. AppBar — górny panel.
Navigator — stos tras (Routes). Navigator.push — otwórz ekran (zwraca Future). Navigator.pop — zamknij (z wynikiem). MaterialPageRoute — animowane przejście (przesunięcie z prawej). Named Routes — identyfikatory tekstowe. onGenerateRoute — scentralizowany handler. Navigator 2.0 (Router + RouteInformationParser + RouterDelegate) — deklaratywna nawigacja dla web, deep linking i złożonych scenariuszy.
Navigator 2.0 — deklaratywna nawigacja. Router — centralny Widget. RouteInformationParser — parsowanie URL. RouterDelegate — zarządzanie stosem. GoRouter (pakiet) — uproszczona otoczka nad Navigator 2.0. Obsługuje: nazwane trasy, parametry, przekierowania, deep linking. IT Sectr zaleca GoRouter dla większości projektów i Navigator 2.0 tylko dla złożonych scenariuszy (web, desktop).
FutureBuilder — Widget budujący UI w oparciu o Future. connectionState: none, waiting, active, done. Używane do: żądań HTTP, odczytu BD, timerów. StreamBuilder — Widget dla Stream (nieskończony strumień danych). snapshot.data, snapshot.hasError, snapshot.hasData. Używane do: WebSocket, Firebase, aktualizacji lokalizacji. Oba Widgety przebudowują się po otrzymaniu nowych danych.
Provider — prosty DI + zarządzanie stanem. ChangeNotifierProvider, MultiProvider. Riverpod — nowoczesna zamiana Providera: bezpieczny w kompilacji, niezależny od BuildContext. Bloc — architektura Event-Driven: Cubit (proste zdarzenia) vs Bloc (złożone). GetX — lekkie zarządzanie stanem + DI + routing. setState — najprostsze, dla lokalnego stanu. IT Sectr zaleca Riverpod dla nowych projektów i Provider dla istniejących.
MediaQuery — rozmiar ekranu, orientacja, platforma, textScaleFactor. MediaQuery.of(context).size.width. ThemeData — motyw aplikacji: kolory, czcionki, kształty. Theme.of(context).textTheme.bodyLarge. Hot Reload — wstrzykiwanie kodu do działającej aplikacji. Zachowuje stan. Nie obsługuje: zmiany main(), zmiennych globalnych, pól statycznych. Hot Restart — pełny restart aplikacji (utrata stanu). Hot Reload — główna zaleta Fluttera dla programistów.
| Typ Widgeta | Opis | Przykłady |
|---|---|---|
| StatelessWidget | Niezmienny, build raz | Text, Icon, Padding, Center |
| StatefulWidget | Zmienny, setState przebudowa | TextField, Checkbox, AnimationController |
| InheritedWidget | Przekazywanie danych w dół | Theme, MediaQuery, Navigator |
| ProxyWidget | Otoczka dla innych Widgetów | ParentDataWidget (Positioned, Expanded) |
| RenderObjectWidget | Tworzy RenderObject | Column, Row, Stack (niestandardowe) |
StatelessWidget — do treści statycznych. StatefulWidget — do treści dynamicznych. InheritedWidget — do DI. IT Sectr zaleca domyślnie StatelessWidget i StatefulWidget tylko w razie potrzeby.
LayoutBuilder — adaptacja do wymiarów rodzica. OrientationBuilder — adaptacja do orientacji. Expanded vs Flexible — dystrybucja miejsca w Row/Column. MediaQuery — punkty graniczne dla tabletów i desktopów. SafeArea — marginesy od elementów systemowych (notch, pasek stanu). AspectRatio — zachowanie proporcji. IT Sectr zaleca LayoutBuilder dla adaptacyjnych układów i OrientationBuilder dla orientacji poziomej.
Testy jednostkowe — testowanie logiki biznesowej, repozytoriów, modeli. dart test — uruchomienie. Testy Widgetów — testowanie widgetów w izolacji. WidgetTester — pumpWidget, tap, enterText. Testy integracyjne — pełne scenariusze na rzeczywistym urządzeniu/emulatorze. Mockito — mockowanie zależności. Golden testy — porównywanie zrzutów ekranu (pliki golden). IT Sectr zaleca testy Widgetów dla każdego ekranu i testy jednostkowe dla logiki biznesowej.
void main() {
testWidgets('Counter increments on tap', (tester) async {
await tester.pumpWidget(const MaterialApp(home: CounterWidget()));
expect(find.text('0'), findsOneWidget);
await tester.tap(find.byType(FloatingActionButton));
await tester.pump();
expect(find.text('1'), findsOneWidget);
});
}Animacje niejawne — AnimatedContainer, AnimatedOpacity, AnimatedPadding, TweenAnimationBuilder. Zmiany właściwości są automatycznie animowane. Animacje jawne — AnimationController z Tween. forward() / reverse(). Animacja Hero — Widget Hero z tagiem — animacja przejścia między ekranami. Animacja stopniowana — łańcuch animacji z Interval. Lottie — integracja animacji After Effects. Rive — interaktywne animacje (state machine). IT Sectr zaleca AnimatedContainer w 80% przypadków i AnimationController dla złożonych scenariuszy.
class AnimatedBox extends StatefulWidget {
@override
State<AnimatedBox> createState() => _AnimatedBoxState();
}
class _AnimatedBoxState extends State<AnimatedBox> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => setState(() => _expanded = !_expanded),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: _expanded ? 200 : 100,
height: _expanded ? 200 : 100,
color: _expanded ? Colors.blue : Colors.red,
child: const Center(child: Text('Tap me')),
),
);
}
}http — prosty klient HTTP (get, post, put, delete). dio — zaawansowany klient z interceptorem, timeoutami, ponawianiem, logowaniem. graphql_flutter — klient GraphQL dla Fluttera. json_serializable — generowanie fromJson/toJson przez adnotacje. Retrofit Dart — type-safe klient HTTP jak Retrofit. WebSocket — przez web_socket_channel. Firebase — Cloud Firestore, Realtime Database, Cloud Functions. IT Sectr zaleca dio dla REST API i graphql_flutter dla GraphQL.
Flutter DevTools — zestaw narzędzi: Inspector (drzewo widgetów), Timeline (wydajność), Memory, Network, Logging. Profile mode — profilowanie bez debugowania. Performance overlay — FPS, czasy budowania. Flame chart — śledzenie wykresu płomieni. DevTools — niezbędne narzędzie do optymalizacji aplikacji Flutter w produkcji.
Flutter Web — kompilacja Fluttera do WASM (WebAssembly). CanvasKit (Skia) vs HTML renderer. CanvasKit — pixel-perfect, ale cięższy. HTML renderer — lekki, ale z ograniczeniami. WASM (Flutter 3.22+) — natywna wydajność. Responsywna adaptacja przez LayoutBuilder i MediaQuery. IT Sectr zaleca CanvasKit dla desktopowych aplikacji webowych i HTML renderer dla stron treściowych.
Często zadawane pytania
StatelessWidget — niezmienny, build raz. StatefulWidget — ze zmiennym Stanem i setState().
Widget Tree — konfiguracja. Element Tree — most. RenderObject Tree — renderowanie (rozmiary, rysowanie).
BuildContext — pozycja Widgeta w drzewie. InheritedWidget — przekazywanie danych w dół (Theme, MediaQuery).
Navigator — stos ekranów. push() → pop(). Named Routes — nazwy tekstowe. Navigator 2.0 — deklaratywny.
Hot Reload — wstrzykiwanie kodu w 1-2 sekundy, zachowanie stanu. Hot Restart — pełny restart.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.