fabriziog
fabriziog

Reputation: 419

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

Upvotes: 4

Views: 7700

Answers (3)

halface_sun
halface_sun

Reputation: 429

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;

}

Upvotes: 3

Pavel
Pavel

Reputation: 5876

Consider using DraggableScrollableSheet class or sliding up panel package

Upvotes: 9

Benjamin
Benjamin

Reputation: 6171

I would recommend the PageView widget, you can see more here and view the documentation.

Using the scrollDirection property, you can set it to vertical so that you can swipe up to reveal a new page and you can swipe down to go back.

Upvotes: 0

Related Questions