Flutter SliverAppBar с согласованным контентом?

Я пытаюсь создать AppBar который будет показывать некоторый контент, когда он уже свернут, и показывать еще некоторый контент, когда он расширен.

Что у меня сейчас:

Желаемый результат состоит в том, что красный и синий контейнеры остаются видимыми, когда SliverAppBar свернут, а при расширении открывается зеленый контейнер.

Я пытался:

      class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: CustomScrollView(
        slivers: [
          TestAppBar(),
          SliverList(
            delegate:
                SliverChildBuilderDelegate((BuildContext context, int index) {
              return Center(child: Text('text'));
            }, childCount: 100),
          )
        ],
      ),
    );
  }
}

class TestAppBar extends StatelessWidget {
  const TestAppBar({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SliverAppBar(
      elevation: 0,
      titleSpacing: 0,
      centerTitle: false,
      pinned: true,
      title: Text('Test app bar'),
      shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(20),
              bottomRight: Radius.circular(20))),
      collapsedHeight: 254,
      expandedHeight: 436 + MediaQuery.of(context).viewPadding.top,
      backgroundColor: Colors.grey,
      flexibleSpace: FlexibleSpaceBar(
        background: Padding(
          padding:
              EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top + 44),
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.red, height: 100),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.blue, height: 100),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.green, height: 100),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Я также пытался сделать эту работу, используя SliverPersistentHeaderDelagate, но и там не повезло:

      class TestPageHeader extends SliverPersistentHeaderDelegate {
  final double minHeight = 200;
  final double maxHeight = 500;
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {

    return SizedBox.expand(child: LayoutBuilder(
      builder: (_, constraints) {
        return Container(
          decoration: const BoxDecoration(
              color: Colors.red,
              borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(20),
                  bottomRight: Radius.circular(20))),
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.red, height: 100),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.blue, height: 100),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(color: Colors.green, height: 100),
              )
            ],
          )
        );
      },
    ));
  }

  @override
  double get maxExtent => maxHeight;

  @override
  double get minExtent => minHeight;

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    return maxExtent != oldDelegate.maxExtent ||
        minExtent != oldDelegate.minExtent;
  }
}

Возможно ли добиться этого с помощью SliverAppBar или SliverPersistentHeaderDelegate?

0 ответов

Другие вопросы по тегам