Использование SliverPersistentHeader без этого Заголовок сжимается, но просто исчезает во Flutter Web

avatar
Tom
9 августа 2021 в 00:34
226
1
0

Я создаю веб-сайт и хотел бы иметь как SliverAppBar, так и SliverPersistentHeader с каруселью изображений. Это я могу сделать полностью, но я не хочу, чтобы карусель изображений сжималась при прокрутке вниз. Вместо этого я бы хотел, чтобы SliverAppBar исчез, но без уменьшения ширины, а только с уменьшением высоты. Я надеюсь, что моя проблема ясна. Если есть вопросы, спрашивайте. Вот мой код:

import 'package:flutter/material.dart';
import 'package:flutter_app/Widgets/HomePageWidgets/ImageCarousel.dart';
import '../Widgets/GlobalWidgets/TopNavBar.dart';
//import 'package:flutter_app/Widgets/HomePageWidgets/HomePageImage.dart';
import '../Widgets/GlobalWidgets/BottomBar.dart';
import '../Widgets/HomePageWidgets/ImageCarousel.dart';
import '../Widgets/GlobalWidgets/OneCard.dart';
import '../Widgets/GlobalWidgets/TwoCards.dart';


class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var screenSize = MediaQuery.of(context).size;
    return Material(
      child: Container(
        child: CustomScrollView (
          slivers: [
            // HomePageImage(), //wurde durch ImageCarousel() ersetzt
            SliverAppBar(
              expandedHeight: screenSize.height * 0.9,
              backgroundColor: Colors.white.withOpacity(1),
              flexibleSpace: ImageCarousel(), // AUTOPLAY MUSS ANGESTELLT WERDEN,
              ),
            SliverList(delegate: SliverChildListDelegate([
              //ImageCarousel(), // AUTOPLAY MUSS ANGESTELLT WERDEN
              Expanded(
                child: Container(

                  child: Row(
                    // Die Row mache ich nur hin, damit ich die Seite zentrieren kann. Wenn alles nach links soll, dann einfach Row entfernen
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      TopNavBar(),
                    ],
                  ),
                ),
              ), //TopNavBar // TODO 1: DropDownButton muss noch erstellt werden // TODO 2: Funktionen zu den Buttons müssen hinzufügt werden
              OneCard(),
              Container(height: 1000,
                width: 500,),
              BottomBar(), // TODO 3: Funktionen zu den Buttons müssen hinzufügt werden
            ]))
          ],
        ),
      ),
    );
  }
}

Это моя карусель изображений:

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';

// https://pub.dev/packages/carousel_slider Link zum Package


class ImageCarousel extends StatefulWidget {
  @override
  _ImageCarouselState createState() => _ImageCarouselState();
}

class _ImageCarouselState extends State<ImageCarousel> {

  List imgList = [
    'assets/images/Mathildedoppelt.jpeg',
    'assets/images/reveuse2.jpeg',

  ];

  @override
  Widget build(BuildContext context) {
    var screenSize = MediaQuery.of(context).size;
    final double height = MediaQuery.of(context).size.height;
    return CarouselSlider(
      options: CarouselOptions(
        height: screenSize.height * 0.9, //Ich kann hier einfach * 1.2 rechnen und dann füllt es den ganzen Bildschirm aus
        aspectRatio: 16/9,
        viewportFraction: 1,
        initialPage: 0,
        enableInfiniteScroll: true,
        reverse: false,
        autoPlay: false, // AUTOPLAY MUSS UNBEDINGT AN
        autoPlayInterval: Duration(seconds: 6),
        autoPlayAnimationDuration: Duration(seconds: 3),
        enlargeCenterPage: false,
        scrollDirection: Axis.horizontal,
      ),
      items: imgList
          .map((item) => Container(
        child: Center(
            child: Image.network(
              item,
              fit: BoxFit.cover,
              height: height,
            )),
      ))
          .toList(),
    );
  }
}

Это код с SliverPersistentHeader:

import 'package:flutter/material.dart';
import 'package:flutter_app/Widgets/HomePageWidgets/ImageCarousel.dart';
import '../Widgets/GlobalWidgets/TopNavBar.dart';
//import 'package:flutter_app/Widgets/HomePageWidgets/HomePageImage.dart';
import '../Widgets/GlobalWidgets/BottomBar.dart';
import '../Widgets/HomePageWidgets/ImageCarousel.dart';
import '../Widgets/GlobalWidgets/OneCard.dart';
import '../Widgets/GlobalWidgets/TwoCards.dart';


class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var screenSize = MediaQuery.of(context).size;
    return Material(
      child: Container(
        child: CustomScrollView (
          slivers: [
            // HomePageImage(), //wurde durch ImageCarousel() ersetzt
            /*SliverAppBar(
              expandedHeight: screenSize.height * 0.9,
              backgroundColor: Colors.white.withOpacity(1),
              flexibleSpace: ImageCarousel(), // AUTOPLAY MUSS ANGESTELLT WERDEN,
              ),*/
            SliverPersistentHeader(
              delegate: MyDynamicHeader(),
            ),
            SliverList(delegate: SliverChildListDelegate([
              //ImageCarousel(), // AUTOPLAY MUSS ANGESTELLT WERDEN
              Expanded(
                child: Container(

                  child: Row(
                    // Die Row mache ich nur hin, damit ich die Seite zentrieren kann. Wenn alles nach links soll, dann einfach Row entfernen
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      TopNavBar(),
                    ],
                  ),
                ),
              ), //TopNavBar // TODO 1: DropDownButton muss noch erstellt werden // TODO 2: Funktionen zu den Buttons müssen hinzufügt werden
              OneCard(),
              SizedBox(height: 20,),
              TwoCards(),
              Container(height: 1000,
                width: 500,),
              BottomBar(), // TODO 3: Funktionen zu den Buttons müssen hinzufügt werden
            ]))
          ],
        ),
      ),
    );
  }
}


class MyDynamicHeader extends SliverPersistentHeaderDelegate {

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return ImageCarousel();
  }

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate _) => true;

  @override
  double get maxExtent => 650.0;

  @override
  double get minExtent => 0.0;
}
Источник
Yeasin Sheikh
9 августа 2021 в 00:39
0

вы можете включить ImageCarousel?

Tom
9 августа 2021 в 01:00
0

Теперь он включен :)

Yeasin Sheikh
9 августа 2021 в 01:22
1

хорошо, тебе нравится иметь SliverPersistentHeader? Но я не могу найти реализацию вашего кода, например расширение SliverPersistentHeaderDelegate.

Tom
9 августа 2021 в 01:28
0

Я попытался реализовать SliverPersistentHeader, но карусель изображений по-прежнему уменьшалась по ширине. Как мне создать свой SliverPersistentHeader, чтобы карусель изображений уменьшалась по высоте, но не по ширине?

Yeasin Sheikh
9 августа 2021 в 01:37
0

Дело происходит здесь. Когда я прокручиваю вверх, наше изображение становится меньше на основе SliverPersistentHeader, вы хотите заполнить ширину изображением? также, если вы отметите контрольный размер изображения, он полностью зависит от aspectRatio из CarouselSlider.

Tom
9 августа 2021 в 01:40
0

Я добавил код с SliverPersistentHeader. Я в основном хочу ту же анимацию, что и на этом веб-сайте: mariotestino.com Вы понимаете мою проблему?

Yeasin Sheikh
9 августа 2021 в 01:43
0

Я думаю, что это даже не использование заголовка, это дополнительный слой в стеке.

Tom
9 августа 2021 в 01:44
0

Давайте продолжим это обсуждение в чате.

Ответы (1)

avatar
Yeasin Sheikh
9 августа 2021 в 02:03
0

В свопе не хватает одной вещи, он будет отображать только полное изображение при свопе, например, при свопинге 2 изображения отображаются на экране. Но функция анимации не работает для carousel_slider.. Хотя, надеюсь, это даст вам представление. В этом случае я могу выбрать auto scrollList и использовать контроллер.

Демонстрационный код:

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';

class CustomSS extends StatefulWidget {
  CustomSS({Key? key}) : super(key: key);

  @override
  _CustomSSState createState() => _CustomSSState();
}

class _CustomSSState extends State<CustomSS> {
  final CarouselController controller = CarouselController();

  final imageList = [
    'assets/me.jpg',
    'assets/ocean.jpg',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LayoutBuilder(
        builder: (context, constraints) => Stack(
          children: [
            Align(
              alignment: Alignment.topCenter,
              child: _ImageCarouselState(
                controller: controller,
                imgList: imageList,
                size: Size(
                  constraints.maxWidth,
                  constraints.maxHeight * .4,
                ),
              ),
            ),
            Positioned(
              child: SizedBox(
                height: constraints.maxHeight,
                width: constraints.maxWidth,
                child: CustomScrollView(
                  slivers: [
                    SliverList(
                      delegate: SliverChildListDelegate(
                        [
                          ///ToolBar
                          SizedBox(
                            height: constraints.maxHeight * .4 + kToolbarHeight,
                            child: GestureDetector(
                              onHorizontalDragEnd: (details) {
                                if (details.primaryVelocity! > 0) {
                                  controller.previousPage();
                                }

                                // Swiping in left direction.
                                else if (details.primaryVelocity! < 0.0) {
                                  controller.nextPage();
                                }
                              },
                            ),
                          ),
                          Column(
                            children: List.generate(
                              122,
                              (index) => Container(
                                height: 100,
                                width: constraints.maxWidth,
                                color:
                                    index.isEven ? Colors.red : Colors.yellow,
                              ),
                            ),
                          ),
                        ],
                      ),
                    )
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _ImageCarouselState extends StatelessWidget {
  final Size size;
  final List imgList;
  final CarouselController controller;
  _ImageCarouselState({
    Key? key,
    required this.size,
    required this.controller,
    required this.imgList,
  }) : super(key: key);
  @override
  Widget build(
    BuildContext context,
  ) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        CarouselSlider(
          carouselController: controller,
          options: CarouselOptions(
            height: size.height,
            // height: screenSize.height *
            //     0.9, //Ich kann hier einfach * 1.2 rechnen und dann füllt es den ganzen Bildschirm aus
            aspectRatio: 16 / 9,
            viewportFraction: 1,
            initialPage: 0,
            enableInfiniteScroll: true,
            reverse: false,
            // autoPlay: true, // AUTOPLAY MUSS UNBEDINGT AN
            // autoPlayInterval: Duration(seconds: 1),
            // autoPlayAnimationDuration: Duration(seconds: 1),
            enlargeCenterPage: false,
            // scrollDirection: Axis.horizontal,
          ),
          items: imgList
              .map((item) => Container(
                    width: size.width,
                    child: Center(
                        child: Image.network(
                      item,
                      fit: BoxFit.cover,
                    )),
                  ))
              .toList(),
        ),
        Container(
          height: kToolbarHeight,
          color: Colors.cyanAccent,
          width: size.width,
          child: Row(
            children: [
              Text(
                "TabBar",
              ),
              Text(
                "Or others",
              ),
              Text(
                "Items",
              ),
            ],
          ),
        )
      ],
    );
  }
}