Несколько SliverAppBar в CustomScrollView - PullRequest
0 голосов
/ 05 мая 2019

Мне нужно иметь несколько SliverAppBar, каждый со своим собственным SliverList в одном представлении. В настоящее время только первый SliverAppBar отвечает правильно.

Конечно, я проделал расширенный поиск в SO и Google, но пока не нашел решения!

  @override
  Widget build(BuildContext context) {
     return Scaffold(
        appBar: AppBar(
          title: Text('Details'),
        ),
        body: CustomScrollView(
          slivers: <Widget>[
            new SliverAppBar(
              floating: true,
              automaticallyImplyLeading: false,
              title: Text('1'),
            ),
            new SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(title: Text('Text 1')),
                childCount: 20,
              ),
            ),
            new SliverAppBar(
              automaticallyImplyLeading: false,
              title: Text('2'),
              floating: true,
            ),
            new SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(title: Text('Text 2')),
                childCount: 20,
              ),
            ),
          ],
        ),
      );
  }

Если вы делаете прокрутку, я ожидаю, что заголовок "2" также будет плавать, когда вы прокручиваете список.

1 Ответ

0 голосов
/ 06 мая 2019

Кажется, это ограничение CustomScrollView.Это можно обойти, но это очень сложно, если у вас нет элементов фиксированной высоты и списков фиксированной длины.Если это так, вы можете принять высоту всего сеанса (AppBar высота + высота каждого элемента списка).

Взгляните:

class Foo extends StatefulWidget {
  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> {
  static const double listItemHeight = 50;
  static const int listItemCount = 15;

  static const double sessionHeight = kToolbarHeight + (listItemCount * listItemHeight);

  int floatingAppBarIndex;
  ScrollController controller;

  @override
  void initState() {
    super.initState();
    floatingAppBarIndex = 0;
    controller = ScrollController()..addListener(onScroll);
  }

  void onScroll() {
    double scrollOffset = controller.offset;
    int sessionsScrolled = 0;

    while (scrollOffset > sessionHeight) {
      scrollOffset -= sessionHeight;
      sessionsScrolled++;
    }

    if (sessionsScrolled != floatingAppBarIndex) {
      setState(() {
        floatingAppBarIndex = sessionsScrolled;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details'),
      ),
      body: CustomScrollView(
        controller: controller,
        slivers: <Widget>[
          new SliverAppBar(
            floating: floatingAppBarIndex == 0,
            automaticallyImplyLeading: false,
            title: Text('1'),
          ),
          new SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return SizedBox(
                  height: listItemHeight,
                  child: ListTile(
                    title: Text('Text 1'),
                  ),
                );
              },
              childCount: listItemCount,
            ),
          ),
          new SliverAppBar(
            floating: floatingAppBarIndex == 1,
            automaticallyImplyLeading: false,
            title: Text('2'),
          ),
          new SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return SizedBox(
                  height: listItemHeight,
                  child: ListTile(
                    title: Text('Text 2'),
                  ),
                );
              },
              childCount: listItemCount,
            ),
          ),
        ],
      ),
    );
  }
}

Как я уже сказал, вы 'Мы все еще можем сделать это в списке со значениями переменных (высота элемента и длина списка), но это будет очень сложно.Если это ваш случай, я рекомендую использовать один из следующих плагинов: https://pub.dartlang.org/packages/sticky_headers https://pub.dartlang.org/packages/flutter_sticky_header

...