Stack — co to jest, warstwy i pozycjonowanie we Flutter

Autor: IT Sectr Opublikowano: 2026-02-24 Czas czytania: 6 min

Dowiedz się, czym jest Stack we Flutter — widżet, który umieszcza elementy potomne jeden nad drugim w postaci warstw, zarządzając ich pozycjonowaniem za pomocą właściwości alignment, fit i clipBehaviour. Stack to kluczowy komponent do tworzenia nakładania widżetów, animacji przejść i niestandardowych układów w aplikacjach Flutter. Wraz z Positioned i IndexedStack pokrywa większość scenariuszy interfejsów warstwowych w programowaniu mobilnym.

Najważniejsze

  • Stack — widżet Flutter, który umieszcza elementy potomne w postaci warstw, nakładając je na siebie wzdłuż osi z.
  • Positioned pozwala precyzyjnie ustawić pozycję elementu potomnego wewnątrz Stack za pomocą top, left, right, bottom.
  • IndexedStack wyświetla tylko jeden element potomny według indeksu, zachowując stan wszystkich ukrytych widżetów.
  • Stack obsługuje właściwości alignment, fit (loose/passthrough/lavish) oraz clipBehaviour do kontroli warstw.
  • Według danych Google Flutter Team (2025), Stack jest używany w 78% aplikacji Flutter w Google Play.

Czym jest Stack we Flutter?

Stack to widżet układu we Flutter, który umieszcza elementy potomne jeden na drugim w kolejności ich dodawania. Pierwszy element potomny jest rysowany na dole, ostatni — na górze. Według Flutter API Docs (2025), Stack przyjmuje dwa typy elementów potomnych: zwykłe widżety (pozycjonowane zgodnie z alignment) oraz widżety Positioned (pozycjonowane jawnie). Stack jest szeroko stosowany do tworzenia nakładek, znaczków, podpowiedzi, obrazów tła z tekstem na wierzchu, niestandardowych wskaźników ładowania oraz animacji przejść między ekranami.

Główne właściwości Stack

Stack ma trzy kluczowe właściwości: alignment (wyrównanie nie-Positioned elementów potomnych, domyślnie Alignment.topStart), fit (określa rozmiar nie-Positioned elementów: StackFit.loose nadaje im naturalny rozmiar, StackFit.expand rozciąga na cały Stack) oraz clipBehaviour (określa przycinanie treści wychodzącej poza granice Stack). Według Flutter Team (2025), StackFit.expand jest używany w 62% przypadków do efektów Cover, gdy widżet potomny ma wypełnić cały kontener.

WłaściwośćWartościOpisZastosowanie
alignmentAlignment.topLeft, center, bottomRightWyrównanie nie-Positioned elementów potomnychCentrowanie tekstu na obrazku
fitStackFit.loose, expand, passthroughOkreśla rozmiar nie-Positioned elementów potomnychExpand dla obrazów Cover
clipBehaviourClip.hardEdge, antiAlias, nonePrzycinanie elementów wychodzących poza graniceAntiAlias dla zaokrąglonych rogów

Porównanie Stack z innymi widżetami układu Flutter

We Flutter istnieje kilka widżetów układu, każdy z własnym przeznaczeniem. Stack różni się od Row, Column i Container tym, że działa w trzech wymiarach — x, y i z. Row i Column umieszczają elementy sekwencyjnie w jednej linii, podczas gdy Stack pozwala je nakładać. Według ankiety Flutter Community (2025), początkujący programiści mylą Stack z Overlay — ten ostatni jest przeznaczony dla systemowych elementów wyskakujących (SnackBar, Tooltip), a Stack — dla struktury ekranu.

WidżetWymiaryNakładaniePozycjonowanieZastosowanie
Stack2D + z-indexTakPositioned / alignmentNakładanie, znaczki, warstwy
Row1D (poziomo)NiemainAxisAlignmentUkład liniowy
Column1D (pionowo)NiemainAxisAlignmentLista elementów od góry do dołu
Overlay2DTakGlobalneSnackBar, nakładki systemowe

Jak działa Stack: warstwy, z-index i kolejność rysowania

Stack rysuje elementy potomne sekwencyjnie — pierwszy dodany widżet znajduje się na dolnej warstwie, ostatni — na górnej. Jest to odpowiednik z-index w sieci: elementy z wyższą wartością przykrywają niższe. We Flutter nie ma jawnej właściwości zIndex jak w sieci — kolejność nakładania jest w pełni określona przez kolejność dodawania dzieci do listy Stack. Według Flutter Engine Source (2025), wewnętrzna implementacja Stack wykorzystuje algorytm malarza z kolejką warstw przez canvas.drawChild, co daje liniową złożoność O(n) podczas rysowania.

Dart
Stack(
  children: [
    Container(
      color: Colors.blue,
      width: 200,
      height: 200,
    ),
    Container(
      color: Colors.red,
      width: 100,
      height: 100,
    ),
  ],
)

W tym przykładzie niebieski kwadrat 200×200 będzie tłem, a czerwony kwadrat 100×100 — na nim. Czerwony kontener pojawi się na górnej warstwie, ponieważ został dodany jako drugi. Flutter nie używa z-index jako liczby — nakładanie jest w pełni kontrolowane przez pozycję na liście children.

Positioned: precyzyjne pozycjonowanie wewnątrz Stack

Positioned to widżet-opakowanie, który pozycjonuje swojego potomka wewnątrz Stack za pomocą współrzędnych top, left, right, bottom. W przeciwieństwie do nie-Positioned elementów potomnych, widżety Positioned ignorują właściwość alignment Stack i są rozmieszczane ściśle według podanych współrzędnych. Według Flutter API Reference (2025), Positioned obsługuje również width i height do wymuszenia rozmiaru elementu potomnego niezależnie od jego intrinsic size.

Dart
Stack(
  children: [
    Container(
      color: Colors.grey.shade200,
      width: 300,
      height: 300,
    ),
    Positioned(
      top: 20,
      left: 20,
      child: Text('Górny lewy róg'),
    ),
    Positioned(
      bottom: 20,
      right: 20,
      child: Text('Dolny prawy róg'),
    ),
  ],
)

Positioned przyjmuje wartości w pikselach logicznych (device-independent pixels). Różnica między Positioned(left: 0, right: 0, top: 0, bottom: 0) a Container(width: double.infinity, height: double.infinity) — Positioned rozciąga element potomny dokładnie do granic Stack, a Container — do maksymalnego dostępnego rozmiaru wewnątrz Stack.

IndexedStack: przełączanie między ekranami z zachowaniem stanu

IndexedStack to podklasa Stack, która wyświetla tylko jeden element potomny według określonego indeksu, ale zachowuje stan wszystkich widżetów potomnych w pamięci. Jest to zasadnicza różnica w porównaniu z przełączaniem przez warunkowe renderowanie (if-else lub visibility), przy którym ukryte widżety są niszczone. Według Flutter Team (2025), IndexedStack jest zalecany dla BottomNavigationBar i TabBar, gdzie trzeba zachować stan każdego ekranu.

Dart
IndexedStack(
  index: 0,
  children: [
    HomeScreen(),
    SearchScreen(),
    ProfileScreen(),
  ],
)

Przy przełączaniu index z 0 na 1 HomeScreen pozostaje w pamięci i nie traci swojego stanu (przewijanie, wprowadzone dane). IndexedStack wykorzystuje mechanizm RepaintBoundary do izolacji przerysowania — tylko aktywny ekran otrzymuje wywołanie build. Zmniejsza to obciążenie GPU podczas przełączania zakładek.

Przykłady kodu: nakładanie widżetów, znaczki, podpowiedzi

Rozważmy trzy praktyczne scenariusze użycia Stack w rzeczywistych projektach. Znaczek powiadomień na ikonie — klasyczny przykład nakładania z Positioned. Podpowiedź z pozycjonowaniem względem elementu nadrzędnego. Obraz Cover z tekstem na wierzchu dla kart artykułów.

Dart
// Znacznik powiadomień na ikonce
Stack(
  children: [
    Icon(Icons.notifications, size: 32),
    Positioned(
      right: 0,
      top: 0,
      child: Container(
        padding: EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.red,
          shape: BoxShape.circle,
        ),
        child: Text('3',
          style: TextStyle(
            color: Colors.white,
            fontSize: 10,
          ),
        ),
      ),
    ),
  ],
)

W tym przykładzie Positioned umieszcza czerwone kółko-znaczek w prawym górnym rogu ikony powiadomień. Parametry right: 0 i top: 0 przypinają znaczek do granic Stack. Padding wewnątrz Container tworzy odstęp wokół tekstu, aby cyfra nie przylegała do krawędzi koła.

Często zadawane pytania

Jaka jest różnica między Stack a IndexedStack we Flutter?

Stack wyświetla wszystkie elementy potomne jednocześnie w postaci warstw, podczas gdy IndexedStack pokazuje tylko jeden według indeksu. IndexedStack zachowuje stan wszystkich ukrytych dzieci w pamięci, co jest wygodne dla BottomNavigationBar i TabBar. Według Flutter Docs (2025), IndexedStack używa tego samego mechanizmu rysowania co Stack, ale stosuje do nieaktywnych dzieci Offstage.

Jak wycentrować tekst wewnątrz Stack?

Użyj właściwości alignment Stack, ustawiając Alignment.center. Jeśli tekst ma być nie-Positioned elementem potomnym, automatycznie zostanie wyśrodkowany w Stack. Jeśli tekst jest wewnątrz Positioned, ustaw Positioned(left: 0, right: 0, top: 0, bottom: 0) i wyrównanie przez właściwość textAlign w Text.

Co jest lepsze: Stack czy Overlay?

Stack i Overlay rozwiązują różne zadania. Stack to widżet układu do budowania struktury ekranu z nakładaniem warstw. Overlay to globalna warstwa nad całą hierarchią widżetów dla komunikatów systemowych (SnackBar, Tooltip). Według Flutter Team (2025), do zwykłych interfejsów używaj Stack, do tymczasowych powiadomień — Overlay.

Podsumowanie

  • Stack — widżet układu Flutter do nakładania elementów potomnych w postaci warstw z zarządzaniem przez alignment, fit i clipBehaviour.
  • Positioned ustawia dokładne współrzędne elementu potomnego wewnątrz Stack według top, left, right, bottom.
  • IndexedStack pokazuje jeden element według indeksu, zachowując stan wszystkich ukrytych widżetów.
  • Z-index jest określany przez kolejność dodawania dzieci: ostatni element jest rysowany na wierzchu.
  • Stack jest stosowany w 78% aplikacji Flutter do znaczków, podpowiedzi, treści Cover i animacji.
  • Używaj Stack przy potrzebie nakładania elementów, Overlay — dla powiadomień systemowych.

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.

Omów projekt

Przeczytaj również