Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a page that can be slided from the bottom of the screen in Flutter?

How can I create a page that slides from the bottom of the screen and when it passes a certain threshold automatically fills the screen? Something like this:

enter image description here

like image 992
fabriziog Avatar asked Oct 24 '25 11:10

fabriziog


2 Answers

Consider using DraggableScrollableSheet class or sliding up panel package

like image 159
Pavel Avatar answered Oct 27 '25 01:10

Pavel


You can use PageRouteBuilder to build your own navigator transitions.

This is the CustomPageRouteBuilder class as you need, and you can change it into other transitons like scale fade rotate, etc.

class CustomPageRouteBuilder<T> extends PageRouteBuilder<T> {

  CustomPageRouteBuilder({
    this.widget,
  })
    : assert(widget != null),
      super(
        pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
          return widget;
        },
        transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
          final Widget transition = SlideTransition(
            position: Tween<Offset>(
              begin: Offset(0.0, 1.0),
              end: Offset.zero,
            ).animate(animation),
            child: SlideTransition(
              position: Tween<Offset>(
                begin: Offset.zero,
                end: Offset(0.0, -0.7),
              ).animate(secondaryAnimation),
              child: child,
            ),
          );

          return transition;
        },
      );

  final Widget widget;

}

And how to use:

Navigator.push(
  context,
  CustomPageRouteBuilder(
    widget: SecondPage(),
  ),
);

You can check the sample below:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {

  const FirstPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.red,
        child: Center(
          child: Text(
            'First Page',
            style: TextStyle(
              color: Colors.white,
              fontSize: 24.0,
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.arrow_forward_ios,
          color: Colors.white,
        ),
        onPressed: () {
          Navigator.push(
            context,
            CustomPageRouteBuilder(
              widget: SecondPage(),
            ),
          );
        },
      ),
    );
  }

}

class SecondPage extends StatelessWidget {

  const SecondPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.blue,
        child: Center(
          child: Text(
            'Second Page',
            style: TextStyle(
              color: Colors.white,
              fontSize: 24.0,
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.arrow_back_ios,
          color: Colors.white,
        ),
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    );
  }

}

class CustomPageRouteBuilder<T> extends PageRouteBuilder<T> {

  CustomPageRouteBuilder({
    this.widget,
  })
    : assert(widget != null),
      super(
        pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
          return widget;
        },
        transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
          final Widget transition = SlideTransition(
            position: Tween<Offset>(
              begin: Offset(0.0, 1.0),
              end: Offset.zero,
            ).animate(animation),
            child: SlideTransition(
              position: Tween<Offset>(
                begin: Offset.zero,
                end: Offset(0.0, -0.7),
              ).animate(secondaryAnimation),
              child: child,
            ),
          );

          return transition;
        },
      );

  final Widget widget;

}
like image 41
halface_sun Avatar answered Oct 27 '25 01:10

halface_sun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!