›Sumário da série

Quem realmente controla os Slivers?
Do gesto do usuário até o cálculo do layout: entenda o pipeline completo do scroll no Flutter.
Índice
Antes de tudo, esqueça o ListView
Nos artigos anteriores vimos que:
ListView.builder(...)
é apenas uma abstração.
Na prática, o Flutter trabalha com algo muito mais próximo disso:
CustomScrollView(
slivers: [
SliverList(...),
],
)
Ou seja: Quem controla o scroll não é o ListView.
É o CustomScrollView.
O pipeline completo
A melhor forma de entender isso é visualizar o fluxo inteiro.
Usuário
↓
GestureDetector
↓
Scrollable
↓
ScrollPosition
↓
Viewport
↓
Sliver 1
Sliver 2
Sliver 3
↓
Tela
Cada bloco possui uma responsabilidade. E quase nenhum deles conhece detalhes dos outros.
Tudo começa com um gesto
Quando você arrasta o dedo (⬇️) o Flutter não move a tela imediatamente.
Primeiro ele precisa descobrir:
- direção;
- velocidade;
- aceleração;
- momento em que o dedo foi solto.
Esse trabalho pertence ao sistema de gestos (GestureDetector).
Depois disso, entra em ação o widget mais importante do scroll: Scrollable.
O Scrollable
Pouca gente utiliza essa classe diretamente. Mas praticamente todas as listas do Flutter possuem um Scrollable.
Por exemplo:
ListView(...)
internamente cria um Scrollable.
Assim como:
GridView(...)
// e
CustomScrollView(...)
Todos eles utilizam o mesmo mecanismo.
O Scrollable é responsável por transformar o gesto em movimentação. Mas ele ainda não sabe onde a tela está. Para isso existe outra classe.
ScrollPosition
Imagine que o scroll seja apenas um número.
0 px
Depois:
150 px
Depois:
1200 px
Quem guarda esse valor é a ScrollPosition.
Ela representa exatamente onde estamos dentro da área rolável.
Quando fazemos:
final controller = ScrollController();
estamos, na prática, criando um objeto que controla uma ou mais ScrollPosition.
É por isso que conseguimos fazer coisas como:
controller.jumpTo(300);
ou
controller.animateTo(
0,
duration: Duration(milliseconds: 300),
curve: Curves.ease,
);
Esses métodos não movem widgets. Eles apenas alteram a posição do scroll.
O Viewport recebe a nova posição
Agora imagine que a posição mudou para:
1450 px
O Viewport recebe essa informação. E faz uma pergunta muito simples:
Quais Slivers aparecem nessa posição?
Ele não conhece Lists.
Não conhece Grids.
Não conhece AppBars.
Ele apenas conhece uma sequência de Slivers.
Como um Sliver sabe o que fazer?
É aqui que entra uma das classes menos conhecidas do Flutter.
SliverConstraints.
Sempre que um Sliver precisa calcular seu layout, ele recebe um objeto parecido com este:
void performLayout() {
final constraints = this.constraints;
}
Dentro dele existem informações como:
- Posição atual do scroll;
- Tamanho do viewport;
- Direção do scroll;
- Espaço restante disponível.
Em outras palavras: O Flutter entrega todo o contexto necessário para que aquele Sliver tome decisões.
É como se dissesse:
Você possui 640 pixels visíveis. O scroll está na posição 1200. Descubra quanto espaço você ocupa.
A resposta é um SliverGeometry
Depois de fazer seus cálculos, o Sliver responde.
Mas ele não responde com widgets, nem com pixels.
Ele responde com um objeto chamado: SliverGeometry.
Esse objeto informa coisas como:
- Quanto espaço ele ocupa;
- Quanto conteúdo ainda existe;
- Quanto pode ser pintado;
- Quanto pode ser rolado.
Visualmente podemos imaginar essa conversa assim:
Viewport
↓
SliverConstraints
↓
SliverList
↓
SliverGeometry
↓
Viewport
É literalmente um diálogo entre o Viewport e cada Sliver.
Isso acontece para todos os Slivers
Imagine esta tela:
CustomScrollView(
slivers: [
SliverAppBar(...),
SliverList(...),
SliverGrid(...),
SliverToBoxAdapter(...),
],
)
O Viewport conversa com cada um deles.
AppBar
↓
Geometry List
↓
Geometry Grid
↓
Geometry Banner
↓
Geometry
Depois soma todas essas respostas.
Só então ele sabe exatamente o que desenhar.
O que o ScrollController realmente faz?
Depois de entender esse pipeline fica fácil perceber que o ScrollController não controla Slivers. Ele controla a posição do scroll.
Quando você escreve:
controller.animateTo(...)
o fluxo é mais ou menos este:
ScrollController
↓
ScrollPosition
↓
Viewport
↓
Slivers recalculam
↓
Nova tela
Perceba que o Controller nunca conversa diretamente com um SliverList.
Ele apenas altera a posição.
Todo o restante acontece automaticamente.
O verdadeiro modelo mental
Quando você desliza o dedo na tela, o Flutter não “move widgets”.
O que realmente acontece é:
Gesture
↓
ScrollPosition
↓
Viewport
↓
SliverConstraints
↓
Cada Sliver calcula seu layout
↓
SliverGeometry
↓
Viewport monta a nova tela
Depois que esse fluxo fica claro, APIs como SliverPersistentHeader, NestedScrollView, SliverFillRemaining e até comportamentos como o colapso da SliverAppBar deixam de parecer mágicos.
Todos utilizam exatamente o mesmo mecanismo.
Conclusão
Neste artigo, deixamos de olhar para os widgets e passamos a enxergar o motor que realmente move uma interface rolável.
Vimos que o ScrollController altera a posição do scroll, a ScrollPosition representa onde estamos, o Viewport coordena a área visível e cada Sliver recebe um conjunto de SliverConstraints para calcular seu layout, respondendo com uma SliverGeometry.
Esse pipeline é um dos pilares da arquitetura de renderização do Flutter e explica por que o framework consegue combinar diferentes tipos de conteúdo em uma única experiência de scroll, mantendo alta performance.
No próximo artigo vamos sair da teoria e colocar tudo isso em prática.
Agora que entendemos como o Flutter coordena os Slivers, chegou a hora de construir uma tela real usando
CustomScrollView, combinandoSliverAppBar,SliverList,SliverGride outros Slivers para ver essa arquitetura funcionando na prática.



