Flutter : dynamic height for scrollable content inside customScrollView (with sticky behaviors)

1k Views Asked by At

I would like to achieve this result but I can't get my head around it...

Image exemple

The only way I found to "fixed" my header (top) and button (bottom) was to use respectively SliverPinnedHeader (which requires the user of the CustomScrollView widget) and StickySideWidget.bottom.

As I am inside a Column widget, I am required to use the Expanded widget which make the scroll works when the list is long enough, but that also take full screen height even when I only have a few items... I'd like to find a way to remove the Expanded without breaking everything

Here is a simplified code :

import 'package:flutter/material.dart';
import 'package:shared/widgets/commons/safe_area.dart';
import 'package:sliver_tools/sliver_tools.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: ElevatedButton(
                child: Text('Demo'),
                onPressed: () => showModalBottomSheet(
                      backgroundColor: Colors.white,
                      isScrollControlled: true,
                      context: context,
                      builder: (context) => DemoContent(),
                    ))));
  }
}

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

  @override
  Widget build(BuildContext context) {
    final items = List.filled(20, '');

    final bottomSheetClosingLine = Padding(
      padding: const EdgeInsets.only(bottom: 32),
      child: Center(child: Container(color: Colors.grey, height: 4, width: 64)),
    );

    final header = Container(
        padding: const EdgeInsets.all(24),
        color: Colors.blue,
        child: Text('Header'));

    final itemWidget = Padding(
        padding: const EdgeInsets.symmetric(vertical: 16), child: Text('item'));

    final button = Container(
      padding: EdgeInsets.only(top: 24),
      width: double.infinity,
      child: ElevatedButton(onPressed: () {}, child: Text('Save')),
    );

    return SafeArea(
        child: Container(
            constraints: BoxConstraints(
                maxHeight: MediaQuery.of(context).size.height * 0.80),
            padding: EdgeInsets.all(24),
            width: double.infinity,
            child: Column(mainAxisSize: MainAxisSize.min, children: [
              bottomSheetClosingLine,
              Expanded(
                  child: StickySideWidget.bottom( /// Custom widget
                body: CustomScrollView(slivers: [
                  SliverPinnedHeader(child: header),
                  SliverToBoxAdapter(
                      child: Column(
                    children: items.map((item) => itemWidget).toList(),
                  ))
                ]),
                side: button,
              ))
            ])));
  }
}

Edit : I would also like to avoid as much as possible to add an unnecessary library...

1

There are 1 best solutions below

2
On

Try to use this Widget draggableScrollableSheet