'From Bottom Sheet to full screen Scaffold in Flutter

I would like my app have a model bottom sheet. The bottom sheet is shown only when user click a button. The bottom sheet first take up around 0.5 or less of the screen which is enough to show popular choices from a listview. User can pick their choice right from here but they also can drag up to view all the choices. The bottom sheet can only be either half or full screen. Once it go full screen, I expect it behave like a scaffold (user can scroll the list view but can not drag down to a bottom sheet anymore). How can I do it in flutter?

Example

When user drag the bottom sheet up, it turn into a scaffold like the screen on the right.



Solution 1:[1]

[UPDATED] Another slide panels, we_slide:

import 'package:we_slide/we_slide.dart';

final _colorScheme = Theme.of(context).colorScheme;
final double _panelMinSize = 70.0;
final double _panelMaxSize = MediaQuery.of(context).size.height / 2;
return Scaffold(
  backgroundColor: Colors.black,
  body: WeSlide(
    panelMinSize: _panelMinSize,
    panelMaxSize: _panelMaxSize,
    body: Container(
      color: _colorScheme.background,
      child: Center(child: Text("This is the body ?")),
    ),
    panel: Container(
      color: _colorScheme.primary,
      child: Center(child: Text("This is the panel ?")),
    ),
    panelHeader: Container(
      height: _panelMinSize,
      color: _colorScheme.secondary,
      child: Center(child: Text("Slide to Up ??")),
    ),
  ),
);

OR

bottom_sheet:

showFlexibleBottomSheet(
  minHeight: 0,
  initHeight: 0.5,
  maxHeight: 1,
  context: context,
  builder: _buildBottomSheet,
  anchors: [0, 0.5, 1],
  isSafeArea: true,
);

Widget _buildBottomSheet(
    BuildContext context,
    ScrollController scrollController,
    double bottomSheetOffset,
  ) {
    return Material(
        child: Container(
          child: ListView(
            controller: scrollController,
            ...
          ),
        ),
      );
  }

[OUTDATED]

Try this package sliding_sheet:

return SheetListenerBuilder(
  // buildWhen can be used to only rebuild the widget when needed.
  buildWhen: (oldState, newState) => oldState.isAtTop != newState.isAtTop,
  builder: (context, state) {
    return AnimatedContainer(
      elevation: !state.isAtTop ? elevation : 0.0,
      duration: const Duration(milliseconds: 400),
      child: child,
    );
  },
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1