woltapp / wolt_modal_sheet

This package provides a responsive modal with multiple pages, motion animation for page transitions, and scrollable content within each page.
MIT License
511 stars 64 forks source link

Question: Combining NonScrollingWoltModalSheetPage and (vertical) ListView #244

Closed KyrOiko closed 4 months ago

KyrOiko commented 4 months ago

Description

I am using NonScrollingWoltModalSheetPage to create a bottomsheet where it has some static component and a ListView. I would like the ListView to occupy the available space and be scrollable within that space. Normally the Expanded widget would be used for that cause but it does not play well (at least with what I have done for the moment.) Any suggestions in how to make that work? Below I provide some piece of code and footages of what I want to achieve, tell me if something is unclear or if futrther info should provided. Thank you in advance

image Screencast from 01-07-2024 11:53:01 ΜΜ.webm

The only Flex widget in this page is the ListView (ListView.separated)

Page Code

class SessionSelectEligibleBundleScreen extends StatelessWidget {
  const SessionSelectEligibleBundleScreen({
    required this.bundles,
    required this.onConfirmButtonPressed,
    required this.onCancelButtonPressed,
    super.key,
  });

  final List<BoughtBundleData> bundles;
  final VoidCallback onConfirmButtonPressed;
  final VoidCallback onCancelButtonPressed;

  @override
  Widget build(BuildContext context) {
    return EligibleBundlesBaseScreen(
      bundles: bundles,
      title: 'Χρήση του πακέτου',
      subTitle: 'Βρέθηκαν ${bundles.length} πακέτα',
      description: 'Πρόσθεσε την προπόνησή σου στο παρακάτω πακέτο.',
      confirmButtonData: Pressable('Eπιβεβαίωση', onConfirmButtonPressed),
      cancelButtonData: Pressable('Ακύρωση', onCancelButtonPressed),
      bundleListRenderer: (context, bundles) => Container(
        constraints: BoxConstraints(maxHeight: 400),
        child: ListView.separated(
          shrinkWrap: true,
          itemCount: 3 * bundles.length,
          itemBuilder: (context, index) => Container(
            height: 100,
            color: Colors.blueGrey,
            child: Text('$index'),
          ),
          separatorBuilder: (context, index) => SizedBox(height: 10),
        ),
      ),
      titleRenderer: (context, title) => ...
      subTitleRenderer: (context, subtitle) => ...
      descriptionRenderer: (context, description) => ...
      confirmButtonRenderer: (context, buttonData) => ...
      cancelButtonRenderer: (context, buttonData) => ...
    );
  }
}

Use of NonScrollingWoltModalSheetPage

        pageListBuilderNotifier: ValueNotifier(
          (context) => [
            NonScrollingWoltModalSheetPage(
              hasTopBarLayer: false,
              child: EligibleBundlesProviderScreen(
                eligibleBundlesFlow: eligibleBundleFlow,
              ),
            ),
            const SliverWoltModalSheetPage(
              mainContentSlivers: [
                SliverToBoxAdapter(child: Text('SuccessPage')),
              ],
            ),
            const SliverWoltModalSheetPage(
              mainContentSlivers: [
                SliverToBoxAdapter(child: Text('FailurePage')),
              ],
            ),
          ],
        ),
ulusoyca commented 4 months ago

Hi,

I am able to achieve this:

image

Here is the code:

import 'package:demo_ui_components/demo_ui_components.dart';
import 'package:flutter/material.dart';
import 'package:playground/home/pages/modal_page_name.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

class SheetPageWithNonScrollingLayout {
  SheetPageWithNonScrollingLayout._();

  static const ModalPageName pageId = ModalPageName.flexibleLayout;

  static NonScrollingWoltModalSheetPage build({
    bool isLastPage = true,
  }) {
    const textStyle = TextStyle(fontSize: 24, fontWeight: FontWeight.bold);
    return NonScrollingWoltModalSheetPage(
      id: pageId,
      leadingNavBarWidget: const WoltModalSheetBackButton(),
      trailingNavBarWidget: const WoltModalSheetCloseButton(),
      hasTopBarLayer: true,
      navBarHeight: 72.0,
      topBarTitle: const Text('Non-scrolling page'),
      child: Builder(builder: (context) {
        return Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 200,
              child: ColoredBox(
                color: Colors.amber,
                child: Center(child: Text('Sized Box: 200h', style: textStyle)),
              ),
            ),
            Expanded(
              child: Container(
                constraints: BoxConstraints(maxHeight: 400),
                child: ListView.separated(
                  shrinkWrap: true,
                  itemCount: 6,
                  itemBuilder: (context, index) => Container(
                    height: 100,
                    color: Colors.blueGrey,
                    child: Center(child: Text('$index')),
                  ),
                  separatorBuilder: (context, index) => SizedBox(height: 10),
                ),
              ),
            ),
            SizedBox(
              height: 100,
              child: ColoredBox(
                color: Colors.green,
                child: Center(
                  child: Text(
                    "SizedBox: 100h",
                    style: textStyle,
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
            ),
          ],
        );
      }),
    );
  }
}

Let me know if this works, and close the issue if does.