skip to Main Content

I am creating my app using Flutter.
However, I’m encountering difficulties with a particular implementation.

I would like to create a page that floats up from the bottom when a specific button is pressed, similar to the image below.

enter image description here

I’ve been trying various approaches, but it seems different from using showBottomSheet or showModalBottomSheet. What should I attempt to achieve this?

Thank you.

2

Answers


  1. As I know, it’s a liitle bit difficult for you to create your own page transition animation which animate both incoming page and the outcoming page like in your example img, you can check this problem to learn about the workaround.

    If you are not cared about the animation of the old page, maybe you can use a custom page transition to implement the similar page route animation, below is the example code in the flutter official doc

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        const MaterialApp(
          home: Page1(),
        ),
      );
    }
    
    class Page1 extends StatelessWidget {
      const Page1({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Center(
            child: ElevatedButton(
              onPressed: () {
                Navigator.of(context).push(_createRoute());
              },
              child: const Text('Go!'),
            ),
          ),
        );
      }
    }
    
    Route _createRoute() {
      return PageRouteBuilder(
        pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
        transitionsBuilder: (context, animation, secondaryAnimation, child) {
          const begin = Offset(0.0, 1.0);
          const end = Offset.zero;
          const curve = Curves.ease;
    
          var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
    
          return SlideTransition(
            position: animation.drive(tween),
            child: child,
          );
        },
      );
    }
    
    class Page2 extends StatelessWidget {
      const Page2({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: const Center(
            child: Text('Page 2'),
          ),
        );
      }
    }
    
    

    Notice that in the case above you use the transitionBuilder to customize the page switch animation

    by the way flutter did provide an iOS style UI package cupertino which has a CupertinoFullscreenDialogTransition widget. You can check this another question to check out how to use CupertinoFullscreenDialogTransition and here is the offical doc of cupertino

    Login or Signup to reply.
  2. @override
      Widget build(BuildContext context) {
        return SafeArea(
          child: Scaffold(
            backgroundColor: Colors.black,
            body: StreamBuilder<double>(
                stream: paddingController.stream,
                builder: (context, snapshot) {
                  padding = snapshot.hasData ? snapshot.data! : 0;
                  return AnimatedPadding(
                    duration: const Duration(milliseconds: 300),
                    padding: EdgeInsets.only(
                        left: padding, top: padding, right: padding),
                    child: DecoratedBox(
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(padding == 0 ? 0 : 10),
                            topRight: Radius.circular(padding == 0 ? 0 : 10)),
                      ),
                      child: const SizedBox(
                        height: double.infinity,
                        width: double.infinity,
                        child: Center(
                          child: Text('Content...'),
                        ),
                      ),
                    ),
                  );
                }),
            bottomNavigationBar: ColoredBox(
              color: Colors.white,
              child: Row(
                children: [
                  IconButton(
                    onPressed: showDlg,
                    icon: const Icon(Icons.add_circle),
                  ),
                  const Icon(Icons.card_travel),
                ],
              ),
            ),
          ),
        );
      }
    
      void showDlg() {
        paddingController.sink.add(30);
        showModalBottomSheet(
          context: context,
          shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(10),
          )),
          constraints: BoxConstraints(minHeight: 800),
          builder: (context) => const SizedBox(
            width: double.infinity,
            height: double.infinity,
            child: Center(
              child: Text('Dialog Content'),
            ),
          ),
        ).then((value) {
          paddingController.sink.add(0);
        });
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search