Explorar Slivers em Flutter

Tempo de leitura: 8 minutes

Silver é uma parte de uma região rolável que você pode caracterizar para agir excepcionalmente. Você pode utilizar lascas para realizar rolagem personalizada sobre impactos, por exemplo, rolagem versátil. Criar conteúdo rolável no Flutter é extremamente básico, quer você esteja tentando fixar widgets ou criar efeitos de paralaxe. Slivers fornecem um método incrível para supervisionar como vários widgets dentro de um formato agem conforme o usuário rola para cima e para baixo.

Neste artigo, vamos explorar Slivers In Flutter. Também implementaremos um programa de demonstração, descreveremos as propriedades e seus tipos de lascas e como usá-las em suas aplicações em Flutter.

 

Slivers

Sliver é uma parte da zona de rolagem que é utilizada para realizar uma rolagem personalizada sobre o impacto. Como tal, o widget sliver é um corte da viewport. Podemos atualizar a implementação das perspectivas roláveis, por exemplo, ListView, GridView utilizando slivers.

É uma interface de nível inferior que oferece excelente controle sobre a execução de uma região rolável. É valioso ao percorrer um grande número de widgets infantis em uma zona rolável. Como dependem da viewport, ela pode mudar sua forma, tamanho e extensão dependendo de alguns eventos e deslocamento

Flutter dá alguns tipos de lascas, algumas delas são dadas abaixo:

> SliverAppBar
> SliverPersistentHeader
> SliverFixedExtentList
> SliverList
> SliverGrid

Este vídeo mostra como criar Slivers em um flutter e mostrar como usar slivers para criar layouts roláveis em seus aplicativos de flutter e, em seguida, eles serão exibidos em seu dispositivo.

 

Como usar slivers?

É importante observar que a totalidade dos segmentos do sliver deve ser colocada dentro de um CustomScrollView de forma consistente. A partir desse ponto, podemos consolidar a lista de slivers para criar a região rolável personalizada.

CustomScrollView no Flutter é uma visualização de rolagem que nos permite criar diferentes impactos de rolagem, por exemplo, grades, listas e cabeçalhos de extensão. Ele tem uma propriedade sliver onde podemos passar uma lista de widgets que incorporam SliverAppBar, SliverFixedExtentList, SliverList e SliverGrid e assim por diante.

SliverAppBar

SliverAppBar é uma barra de aplicativos de material design no Flutter que se incorpora a um CustomScrollView. Em geral, nós o utilizamos como o principal produto do CustomScrollView. Ele pode mudar de altura e flutuar sobre o outro widget da exibição de rolagem. Permite-nos fazer uma barra de aplicação com diferentes efeitos de rolagem.

SliverAppBar(
   title: Text('Flutter Slivers Demo',style:
   TextStyle(fontSize: 25,
       fontWeight: FontWeight.bold,
       color: Colors.white),),
   backgroundColor: Color(0xFFEDF2F8),
   expandedHeight: 200,
   flexibleSpace: FlexibleSpaceBar(
     background: Image.network(
         "https://images.unsplash.com/photo-1603785608232-44c43cdc0d70?ixlib=rb-1.2.1&%22%22ixid=MXwxMjA3fDB8MHx0b3BpYy1mZWVkfDY4fEo5eXJQYUhYUlFZfHxlbnwwfHx8",
         fit: BoxFit.cover),
   ),
 ),

Neste SliverAppBar, adicionaremos title, expandedHeight e flexibleSpace. Quando executamos o aplicativo, devemos obter a interface do usuário da tela como a captura de tela abaixo.

Saída SliverAppBar
Saída SliverAppBar

 

Propriedades de SliverAppBar

A seguir estão as propriedades básicas do SliverAppBar:

  • actions: Esta propriedade é utilizada para tornar os widgets corretos no título da appBar. Na maioria das vezes, é um iconButton que se comunica com operações regulares.
  • title: Esta propriedade é utilizada para caracterizar o título para o SliverAppBar. É como o título AppBar para dar o nome do aplicativo.
  • leading: Esta propriedade é utilizada para caracterizar um widget à esquerda do título. Na maioria das vezes, é utilizado para colocar o widget Menu Drawer.
  • backgroundColor: Esta propriedade é utilizada para caracterizar uma cor de fundo para a barra de aplicativos do sliver.
  • bottom: Esta propriedade é utilizada para abrir espaço para a parte inferior do título, onde podemos caracterizar qualquer widget conforme indicado por nossas necessidades.
  • expandedHeight: Esta propriedade é utilizada para determinar a altura mais extrema da barra do aplicativo que pode ser estendida durante a rolagem. Deve ser caracterizado em valor duplo.
  • floating: Esta propriedade decide se a barra de aplicação será perceptível ou não quando o suário rolar para a barra de aplicação.
  • flexibleSpace: Esta propriedade é utilizada para caracterizar um widget que é empilhado atrás da barra de ferramentas e da barra de guias. Sua altura é equivalente à altura geral da barra do aplicativo.

 

SliverPersistentHeader

Um sliver cujo tamanho flutua quando o sliver é rolado para a borda da viewport inversamente a GrowthDirection do sliver. Na instância típica de um CustomScrollView sem lasca focalizada, esta lasca mudará seu tamanho quando rolada para a borda principal da viewport.

Crie um novo arquivo dart chamado sliver_header.dart dentro da pasta lib.

return SliverPersistentHeader(
  pinned: true,
  floating: false,
  delegate: Delegate(backgroundColor, _title),
);

Crie uma extensão de classe Delegate com SliverPersistentHeaderDelegate{}

class Delegate extends SliverPersistentHeaderDelegate {
  final Color backgroundColor;
  final String _title;

  Delegate(this.backgroundColor, this._title);

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: backgroundColor,
      child: Center(
        child: Text(
          _title,
          style: TextStyle(
            color: Colors.white,
            fontSize: 25,
          ),
        ),
      ),
    );
  }

  @override
  double get maxExtent => 80;

  @override
  double get minExtent => 50;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }
}

Neste SliverPersistentHeader, adicionaremos title e backgroundColor. Quando executamos o aplicativo, devemos obter a interface do usuário da tela como a captura de tela abaixo.

Saída SliverPersistentHeader
Saída SliverPersistentHeader

 

SliverFixedExtentList

Um SliverFixedExtentList é um sliver que contém vários filhos com uma extensão de eixo fundamental semelhante em uma matriz unidimensional ou matriz linear. É mais produtivo do que SliverList porque não há nenhuma razão convincente para executar layouts em seus filhos para adquirir a extensão do eixo principal. Não permite um intervalo entre seus filhos. Requer que cada filho tenha SliverConstraints.crossAxisExtent no eixo cruzado e a propriedade itemExtent no eixo principal.

SliverFixedExtentList(
  itemExtent: 70,
  delegate: SliverChildListDelegate([
    _buildFixedList(Colors.cyan, "Cyan"),
    _buildFixedList(Colors.green, "Green"),
    _buildFixedList(Colors.orange, "Orange"),
    _buildFixedList(Colors.amberAccent, "AmberAccent"),
    _buildFixedList(Colors.blueGrey, "Blue Grey"),
               ]),
),

Neste SliverFixedExtentList, usaremos itemExtent e delegate. Em delegado, chamaremos uma função SliverChildListDelegate(). Quando executamos o aplicativo, devemos obter a interface do usuário da tela como a captura de tela abaixo.

Saida SliverFixedExtentList
Saida SliverFixedExtentList

 

SliverList

SliverList é um sliver que coloca os filhos em uma matriz linear ou matriz unidimensional. É preciso um parâmetro delegado para fornecer as coisas na lista para que elas rolem para a exibição. Podemos indicar a lista de filhos utilizando um SliverChildListDelegate ou construí-los com um SliverChildBuilderDelegate.

 SliverList(
  delegate: SliverChildListDelegate([
    Container(
      margin: EdgeInsets.all(24),
      child: Form(
        key: _formKey,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Add Name', style: TextStyle(fontSize: 22)),
            _buildName(),
            SizedBox(height: 16),
            ElevatedButton(
              child: Text('Submit'),
              onPressed: _submit,
            ),
          ],
        ),
      ),
    )
  ]),
),

Neste SliverList, adicionaremos TextFormField com validação e ElevationButton(). Quando executamos o aplicativo, devemos obter a interface do usuário da tela como a captura de tela abaixo.

 

SliverGrid

SliverGrids coloca os children em um curso de ação bidimensional. Ele também usa um delegado para indicar os filhos ou uma lista expressa como o SliverList. No entanto, tem mais arranjos para a medição de eixo cruzado em uma grade.

SliverGrid(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 4, mainAxisSpacing: 10, crossAxisSpacing: 10,
      childAspectRatio: 1.5
  ),
  delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
    return Container(
      padding: EdgeInsets.all(8),
      color: _randomColor(index),
      child: Center(
        child: Text(
          _name[index],
          textAlign: TextAlign.center,
          style: TextStyle(color: Colors.white, fontSize: 20),
        ),
      ),
    );
  },
      childCount: _name.length
  ),
)

Neste SliverGrid, vamos inserir qualquer nome no TextFormField, então pressione o botão enviar, e o nome é mostrado abaixo do gridView com cores aleatórias. Quando executamos o aplicativo, devemos obter a interface do usuário da tela como a captura de tela abaixo.

 

Arquivo de código

slivers_demo.dart
import 'package:flutter/material.dart';
import 'package:flutter_slivers_demo/sliver_header.dart';

class SliversDemo extends StatefulWidget {
  @override
  _SliversDemoState createState() => _SliversDemoState();
}

class _SliversDemoState extends State<SliversDemo> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  final List<String> _name = ['tester'];

  Widget _buildName() {
    return TextFormField(
      decoration: InputDecoration(labelText: 'Name'),
      validator: (String value) {
        if (value.isEmpty) {
          return 'Name is required';
        }

        return null;
      },
      onSaved: (String value) {
        setState(() {
          _name.add(value);
        });
      },
    );
  }

  Widget _buildFixedList(Color color, String _text) {
    return Container(
      color: color,
      child: Center(
        child: Text(
          _text,
          style: TextStyle(color: Colors.white, fontSize: 25),
        ),
      ),
    );
  }

  void _submit() {
    if (!_formKey.currentState.validate()) {
      return;
    }

    _formKey.currentState.save();
  }

  @override
  Widget build(BuildContext context) {
    print(_name.toString());

    return Scaffold(
      backgroundColor: Color(0xFFEDF2F8),
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: Text('Flutter Slivers Demo',style:
            TextStyle(fontSize: 25,
                fontWeight: FontWeight.bold,
                color: Colors.white),),
            backgroundColor: Color(0xFFEDF2F8),
            expandedHeight: 200,
            flexibleSpace: FlexibleSpaceBar(
              background: Image.network(
                  "https://images.unsplash.com/photo-1603785608232-44c43cdc0d70?ixlib=rb-1.2.1&%22%22ixid=MXwxMjA3fDB8MHx0b3BpYy1mZWVkfDY4fEo5eXJQYUhYUlFZfHxlbnwwfHx8",
                  fit: BoxFit.cover),
            ),
          ),
          SliverHeader(Colors.red, "SliverPersistentHeader 1"),
          SliverHeader(Colors.blue, "SliverPersistentHeader 2"),
          SliverHeader(Colors.purple, "SliverPersistentHeader 3"),
          SliverFixedExtentList(
            itemExtent: 70,
            delegate: SliverChildListDelegate([
              _buildFixedList(Colors.cyan, "Cyan"),
              _buildFixedList(Colors.green, "Green"),
              _buildFixedList(Colors.orange, "Orange"),
              _buildFixedList(Colors.amberAccent, "AmberAccent"),
              _buildFixedList(Colors.blueGrey, "Blue Grey"),
                         ]),
          ),
          SliverList(
            delegate: SliverChildListDelegate([
              Container(
                margin: EdgeInsets.all(24),
                child: Form(
                  key: _formKey,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text('Add Name', style: TextStyle(fontSize: 22)),
                      _buildName(),
                      SizedBox(height: 16),
                      ElevatedButton(
                        child: Text('Submit'),
                        onPressed: _submit,
                      ),
                    ],
                  ),
                ),
              )
            ]),
          ),
          SliverGrid(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4, mainAxisSpacing: 10, crossAxisSpacing: 10,
                childAspectRatio: 1.5
            ),
            delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
              return Container(
                padding: EdgeInsets.all(8),
                color: _randomColor(index),
                child: Center(
                  child: Text(
                    _name[index],
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
              );
            },
                childCount: _name.length
            ),
          )
        ],
      ),
    );
  }
}

Color _randomColor(int index) {
  if (index % 4 == 0) {
    return Colors.blue;
  } else if (index % 4 == 1) {
    return Colors.orange;
  }else if(index % 4 == 2){
    return Colors.cyan;
  }
  return Colors.red;
}
sliver_header.dart
import 'package:flutter/material.dart';

class SliverHeader extends StatelessWidget {
  final Color backgroundColor;
  final String _title;

  SliverHeader(this.backgroundColor, this._title);

  @override
  Widget build(BuildContext context) {
    return SliverPersistentHeader(
      pinned: true,
      floating: false,
      delegate: Delegate(backgroundColor, _title),
    );
  }
}

class Delegate extends SliverPersistentHeaderDelegate {
  final Color backgroundColor;
  final String _title;

  Delegate(this.backgroundColor, this._title);

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: backgroundColor,
      child: Center(
        child: Text(
          _title,
          style: TextStyle(
            color: Colors.white,
            fontSize: 25,
          ),
        ),
      ),
    );
  }

  @override
  double get maxExtent => 80;

  @override
  double get minExtent => 50;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }
}
splash_screen.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_slivers_demo/slivers_demo.dart';

class Splash extends StatefulWidget {
  @override
  VideoState createState() => VideoState();
}

class VideoState extends State<Splash> with SingleTickerProviderStateMixin {
  var _visible = true;

  AnimationController animationController;
  Animation<double> animation;

  startTime() async {
    var _duration = new Duration(seconds: 2);
    return new Timer(_duration, navigationPage);
  }

  void navigationPage() {
    Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => SliversDemo(),
    ));
  }

  @override
  void initState() {
    super.initState();

    animationController = new AnimationController(
        vsync: this, duration: new Duration(seconds: 1));
    animation =
        new CurvedAnimation(parent: animationController, curve: Curves.easeOut);

    animation.addListener(() => this.setState(() {}));
    animationController.forward();

    setState(() {
      _visible = !_visible;
    });
    startTime();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          new Column(
            mainAxisAlignment: MainAxisAlignment.end,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(bottom: 30.0),
                child: Text(
                  'CapSistema',
                  style: TextStyle(
                    color: Colors.blue.shade800,
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              )
            ],
          ),
          new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Image.asset(
                'assets/devs.jpg',
                width: animation.value * 250,
                height: animation.value * 250,
              ),
            ],
          ),
        ],
      ),
    );
  }
}
main.dart
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_slivers_demo/splash_screen.dart';

class MyHttpoverrides extends HttpOverrides{
  @override 
  HttpClient createHttpClient(SecurityContext context){
    return super.createHttpClient(context)
    ..badCertificateCallback = (X509Certificate cert, String host, int port)=>true;
  }
}

void main() {
  HttpOverrides.global = new MyHttpoverrides();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData.light(),
        debugShowCheckedModeBanner: false,
        home: Splash());
  }
}

Conclusão:

No artigo, expliquei rapidamente algumas propriedades e tipos de Fractius; você pode modificar este código de acordo com sua escolha. Esta foi uma pequena introdução ao Slivers On User Interaction da minha parte, e está funcionando usando o Flutter.

Espero que este blog forneça a você informações suficientes sobre Experimentando Slivers em seus projetos de flutter. Mostraremos os slivers, algumas propriedades usando em slivers e faremos um programa de demonstração para slivers de trabalho e mostraremos como usar slivers para criar layouts roláveis em seus aplicativos de flutter. Então, por favor, tente.