jamesblasco / modal_bottom_sheet

Flutter | Create advanced modal bottom sheets. Material, Cupertino or your own style
https://pub.dev/packages/modal_bottom_sheet
MIT License
1.86k stars 468 forks source link

Show Modal in tablet #166

Open Urkman opened 3 years ago

Urkman commented 3 years ago

Is it possible to show a modal on a tablet like the iOS modal on iPad? So it should not be fullscreen...

bierbaumtim commented 3 years ago

Duplicate of #30

This is the answer @jamesblasco gave in #30 :

That one is the photo is not a ModalBottomSheet and it is considered a Dialog in Flutter. The modal bottom sheet is animated from the bottom while the dialog appears in the middle of the screen.

I would suggest you check the size of the device and use showCupertinoModalBottomSheet for phones and showDialog for tablets.

If you want it to be animated from the bottom but the previous route, not animated you can build your own solution inspired > by showFloatingBottomSheet

I've had the same problem, that I need a FormSheet(which is the type of such modal) and I implemented a route which works in the situations I needed it. But I never compared a native FormSheet with my implementation, so it can work for you. In #30 is a link to a medium article which containts detailed information about the dimensions of a FormSheet.

class IOSFormSheetOverlayRoute<T> extends PageRoute<T> {
  IOSFormSheetOverlayRoute({
    required this.builder,
    this.barrierLabel,
    this.addElevation = true,
    RouteSettings? settings,
  }) : super(
          settings: settings,
        );

  @override
  Color get barrierColor => const Color(0x77000000);

  @override
  bool get barrierDismissible => false;

  @override
  String? barrierLabel;

  @override
  bool get maintainState => false;

  @override
  bool get opaque => false;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 355);

  final WidgetBuilder builder;
  final bool addElevation;

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    final existingMediaQuery = MediaQuery.of(context);

    return FadeTransition(
      opacity: CurvedAnimation(parent: animation, curve: Curves.easeOut),
      child: LayoutBuilder(
        builder: (context, constraints) => MediaQuery.removePadding(
          context: context,
          removeTop: true,
          child: Padding(
            padding: EdgeInsets.only(
              top: existingMediaQuery.viewInsets.top,
              bottom: existingMediaQuery.viewInsets.bottom,
            ),
            child: Center(
              child: ConstrainedBox(
                constraints: BoxConstraints(
                  maxHeight: constraints.maxHeight * 0.52,
                  maxWidth: constraints.maxWidth * 0.65,
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(12),
                  child: CupertinoUserInterfaceLevel(
                    data: addElevation
                        ? CupertinoUserInterfaceLevelData.elevated
                        : CupertinoUserInterfaceLevelData.base,
                    child: builder(context),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
Urkman commented 3 years ago

@bierbaumtim Thanks agin for you code... I now used a dialog on tablets. Looks more natural for me..

This is the code:

                showGeneralDialog(
                  barrierLabel: "",
                  barrierDismissible: true,
                  barrierColor: Colors.black.withOpacity(0.5),
                  transitionDuration: Duration(milliseconds: 300),
                  context: context,
                  pageBuilder: (context, anim1, anim2) => Center(child: PageToDisplay()),
                  transitionBuilder: (context, anim1, anim2, child) {
                    return SlideTransition(
                      position: Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate(anim1),
                      child: child,
                    );
                  },
                );

Perhaps this is also a solution for you :)

Urkman commented 3 years ago

@bierbaumtim This PR : https://github.com/jamesblasco/modal_bottom_sheet/pull/141 added a width, this fixes all my iPad problems :) Hopefully this gets merged asap :) @jamesblasco

westlinkin commented 2 years ago

@bierbaumtim Thanks agin for you code... I now used a dialog on tablets. Looks more natural for me..

This is the code:

                showGeneralDialog(
                  barrierLabel: "",
                  barrierDismissible: true,
                  barrierColor: Colors.black.withOpacity(0.5),
                  transitionDuration: Duration(milliseconds: 300),
                  context: context,
                  pageBuilder: (context, anim1, anim2) => Center(child: PageToDisplay()),
                  transitionBuilder: (context, anim1, anim2, child) {
                    return SlideTransition(
                      position: Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate(anim1),
                      child: child,
                    );
                  },
                );

Perhaps this is also a solution for you :)

should set useRootNavigator to false if we want the same effect as the showCupertinoModalBottomSheet