Crie um rodapé fixo com uma exibição de corpo rolável no Flutter
Crie um widget que contenha um cabeçalho e, mais importante, um rodapé que obviamente deve permanecer no final da tela
Então ?
você dirá Simplesmente usarei o widget EXPANDED sobre meu corpo para que ele ocupe todo o espaço e deixe um pouco na parte superior e inferior do cabeçalho e rodapé Então, o que você está oferecendo!
MAS e se o Body for Scrollable (ex: listview) você sabe com certeza que não pode usar um widget EXPANDEDx sobre um Scrollable Widget.
Se a sua lista sempre tem itens que empurram o rodapé para baixo, então você não tem problema,
mas e se não?
e não se esqueça que sua lista é rolável
para criar um rodapé autoadesivo em vibração, usaremos Slivers,
Uma fatia é uma parte de uma área scrollable que você pode definir para se comportar de uma maneira especial. Você pode usar slivers para obter efeitos scrolling personalizados, como scrolling elástico.
https://flutter.dev/docs/development/ui/advanced/slivers
Bem, vamos começar usando um CustomScroll que funciona com nossos slivers. O primeiro filho será o SliverList que conterá o cabeçalho e o corpo.
Observe que você DEVE usar shrinkWrap:true em sua lista, para que você possa forçar sua lista a ocupar apenas o espaço necessário.
o segundo filho do nosso CustomScroll é o SliverFillRemaining, como o nome indica, vamos colocar o Footer aqui e torná-lo Algin na parte inferior do espaço restante.
observe que o comportamento padrão para o SliverFillRemaining é ter um corpo scroallable para seu filho, não se esqueça de mudar isso.
import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: CustomScrollView( slivers: [ SliverList( delegate: SliverChildListDelegate( [ Container( width: double.infinity, height: 50, color: Colors.orangeAccent, child: Center( child: Text( 'Header', style: TextStyle(color: Colors.white, letterSpacing: 4), ), ), ), ListView.builder( shrinkWrap: true, itemCount: 100, itemBuilder: (BuildContext context, int index) { return ListTile( title: Center(child: Text('$index')), ); }, ), ], ), ), SliverFillRemaining( hasScrollBody: false, child: Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, height: 50, color: Colors.blueAccent, child: Center( child: Text( 'Footer', style: TextStyle(color: Colors.white, letterSpacing: 4), ), ), ), ), ) ], ), ); } }
Você sempre pode substituir este cabeçalho por um widget mais poderoso, SliverAppBar com opções mais sofisticadas, como float, snap, pinned..
ver:
https://api.flutter.dev/flutter/material/SliverAppBar-class.html
import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: CustomScrollView( slivers: [ SliverAppBar( expandedHeight: 100.0, floating: true, pinned: false, snap: false, flexibleSpace: const FlexibleSpaceBar( title: Text('Available seats'), ), actions: <Widget>[ IconButton( icon: const Icon(Icons.add_circle), tooltip: 'Add new entry', onPressed: () {}, ), ]), SliverList( delegate: SliverChildListDelegate( [ // Container( // width: double.infinity, // height: 50, // color: Colors.orangeAccent, // child: Center( // child: Text( // 'Header', // style: TextStyle(color: Colors.white, letterSpacing: 4), // ), // ), // ), ListView.builder( shrinkWrap: true, itemCount: 100, itemBuilder: (BuildContext context, int index) { return ListTile( title: Center(child: Text('$index')), ); }, ), ], ), ), SliverFillRemaining( hasScrollBody: false, child: Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, height: 50, color: Colors.blueAccent, child: Center( child: Text( 'Footer', style: TextStyle(color: Colors.white, letterSpacing: 4), ), ), ), ), ) ], ), ); } }