es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Contenedor animado con lista desplazable – Flutter

Tengo una pantalla bastante complicada que estoy tratando de implementar en Flutter.
Es un scrollview con un fondo parallax y…algo así como una barra de herramientas colapsable.
Sé que probablemente tengo que usar un NestedScrollView y un SliverAppBar(?), pero no estoy seguro por dónde empezar a implementar. Creo que una imagen mostraría mejor lo que estoy tratando de lograr:

enter image description here

La lista comienza debajo de un Container. A medida que desplazas la lista, el Container se reduce a un Container más pequeño y se fija en la parte superior. ¿Tiene sentido eso? ¡Cualquier ayuda sería muy apreciada!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para implementar la pantalla como se muestra en la imagen, se pueden seguir los siguientes pasos:

    1. Utilice un Scaffold con backgroundColor establecido en el color de la parte superior de la pantalla y un CustomScrollView como cuerpo.
    2. Utilice un SliverToBoxAdapter como primer hijo del CustomScrollView para mostrar la imagen de fondo de paralaje. Esto se puede lograr utilizando un Stack con una imagen y un widget Opacity colocados dentro de él.
    3. Utilice un SliverPersistentHeader para el efecto de barra de herramientas colapsable. Dentro de este widget, utilice un Stack con dos widgets Positioned, uno para el contenedor más grande en la parte superior y otro para el contenedor más pequeño que está fijado en la parte superior a medida que el usuario se desplaza hacia abajo.
    4. Utilice un SliverList o un SliverGrid como hijo del CustomScrollView para mostrar los elementos de la lista.

    Los pasos anteriores se pueden implementar utilizando el widget NestedScrollView. El NestedScrollView proporciona soporte para encabezados que se desplazan verticalmente y vistas de desplazamiento secundarias.

    Scaffold(
      backgroundColor: Colors.blueGrey,
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <widget>[
            SliverToBoxAdapter(
              child: Stack(
                children: [
                  Image.network(
                    'https://example.com/image.jpg',
                    fit: BoxFit.cover,
                  ),
                  Opacity(
                    opacity: 0.6,
                    child: Container(
                      color: Colors.black,
                    ),
                  ),
                ],
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: _SliverAppBarDelegate(
                minHeight: 80.0,
                maxHeight: 200.0,
                child: Stack(
                  children: [
                    Positioned(
                      left: 0,
                      right: 0,
                      top: 0,
                      bottom: 0,
                      child: Container(
                        color: Colors.blueGrey,
                        alignment: Alignment.center,
                        child: Text(
                          'Contenedor Grande',
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 24.0,
                          ),
                        ),
                      ),
                    ),
                    Positioned(
                      left: 0,
                      right: 0,
                      top: 0,
                      child: AnimatedContainer(
                        duration: Duration(milliseconds: 300),
                        height: innerBoxIsScrolled ? 40.0 : 80.0,
                        color: Colors.blueGrey,
                        alignment: Alignment.center,
                        child: Text(
                          'Contenedor Pequeño',
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 20.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ];
        },
        body: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return ListTile(
              title: Text('Elemento de lista $index'),
            );
          },
        ),
      ),
    );
    

    El fragmento de código anterior contiene un delegado de encabezado de listón personalizado, _SliverAppBarDelegate, que se utiliza para construir la barra de herramientas colapsable. El widget AnimatedContainer dentro del delegado anima el tamaño del contenedor más pequeño a medida que el usuario se desplaza.

    ¡Espero que esto ayude!

Comments are closed.