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.

Cómo desplazarse con NestedScrollView para usar un Circle Avatar apilado sobre SliverAppBar.

Estoy trabajando en un proyecto de Flutter recientemente y tengo un problema.

Ver foto 1: aquí está mi código: la foto y el texto deberían estar entre el widget TabBar y el fondo rojo como aparece en el diseño (azul).

Aquí puedes ver mi código actual:

class Main

   body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <widget>[
            PortfolioSliverAppBar(_pages[_tabController.index].item1),
            SliverPersistentHeader(
              delegate: SliverPersistentHeaderDelegateImpl(
                tabBar: TabBar(
                  padding: EdgeInsets.only(top: 15.0),
                  labelColor: Colors.black,
                  indicatorColor: Colors.black,
                  indicator: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(18)),
                      color: Colors.blue),
                  controller: _tabController,
                  tabs: _pages
                      .map<tab>((Tuple3 page) => Tab(text: page.item1))
                      .toList(),
                ),
              ),
            ),
          ];
        },
        body: Container(
          margin: EdgeInsets.only(top: 20.0),
          child: TabBarView(
            controller: _tabController,
            children: _pages.map<widget>((Tuple3 page) => page.item2).toList(),
          ),
        ),

class Silver

class SliverPersistentHeaderDelegateImpl extends SliverPersistentHeaderDelegate {
  final TabBar tabBar;
  final Color color;

  const SliverPersistentHeaderDelegateImpl({
    Color color = Colors.transparent,
    @required this.tabBar,
  }) : this.color = color;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: color,
      child: tabBar,
    );
  }

Ver foto 2: aquí está el diseño dado:

mi vista

la UI actual

¡Muchas gracias!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema que se enfrenta en el proyecto Flutter es alinear la foto y el texto entre el widget TabBar y el fondo rojo según el diseño proporcionado. La interfaz de usuario actual no está correctamente alineada con el diseño.

    Para solucionar este problema, debemos ajustar el diseño utilizando el widget Stack para superponer la foto y el texto con el TabBar azul. Aquí están los pasos para lograr esto:

    1. Envuelve el TabBar y SliverPersistentHeader en un widget Stack.
    2. Agrega un widget Positioned para la foto y el texto con los valores correctos de arriba, izquierda y derecha para superponer el TabBar azul.

    3. Establece la propiedad flotante (floating) de SliverPersistentHeader en true y su propiedad fijada (pinned) en false.

    Aquí está el código modificado:

    class Main extends StatefulWidget {
      @override
      _MainState createState() => _MainState();
    }
    
    class _MainState extends State<main> with SingleTickerProviderStateMixin {
      TabController _tabController;
      List<><string, widget,="" icondata="">> _pages = [];
    
      @override
      void initState() {
        super.initState();
        _tabController = TabController(length: _pages.length, vsync: this);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              Positioned(
                top: 80.0,
                left: 0.0,
                right: 0.0,
                child: Image.asset(
                  'assets/image.jpg',
                  fit: BoxFit.cover,
                ),
              ),
              Positioned(
                top: 120.0,
                left: 20.0,
                right: 20.0,
                child: Text(
                  'Lorem ipsum dolor sit amet',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 24.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              NestedScrollView(
                headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                  return <widget>[
                    SliverAppBar(
                      backgroundColor: Colors.red,
                      expandedHeight: 250.0,
                    ),
                    SliverPersistentHeader(
                      delegate: SliverPersistentHeaderDelegateImpl(
                        tabBar: TabBar(
                          padding: EdgeInsets.only(top: 15.0),
                          labelColor: Colors.black,
                          indicatorColor: Colors.black,
                          indicator: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(18)),
                            color: Colors.blue,
                          ),
                          controller: _tabController,
                          tabs: _pages
                              .map<tab>((Tuple3 page) => Tab(text: page.item1))
                              .toList(),
                        ),
                      ),
                      floating: true,
                      pinned: false,
                    ),
                  ];
                },
                body: Container(
                  margin: EdgeInsets.only(top: 180.0),
                  child: TabBarView(
                    controller: _tabController,
                    children: _pages.map<widget>((Tuple3 page) => page.item2).toList(),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
    
    class SliverPersistentHeaderDelegateImpl extends SliverPersistentHeaderDelegate {
      final TabBar tabBar;
    
      const SliverPersistentHeaderDelegateImpl({
        @required this.tabBar,
      });
    
      @override
      Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
        return Container(
          child: tabBar,
        );
      }
    
      @override
      double get maxExtent => tabBar.preferredSize.height + 15.0;
    
      @override
      double get minExtent => tabBar.preferredSize.height + 15.0;
    
      @override
      bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
        return false;
      }
    }
    

    Este código alineará correctamente la foto y el texto entre el TabBar y el fondo rojo según el diseño proporcionado.</string,>

Comments are closed.