Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why there is a shadow between nested navigator?

Tags:

flutter

When i use navigator nested in MaterialApp that contains a navigator, there is shadow as showed in the following image.

Why? How to remove this shadow?

enter image description here

My code is here:

import 'package:flutter/material.dart';

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

class NavigatorNested extends StatefulWidget {
    @override
    NavigatorNestedState createState() => NavigatorNestedState();
}

class NavigatorNestedState extends State<NavigatorNested> {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            initialRoute: 'hpme',
            title: 'test',
            theme: ThemeData(
                primarySwatch: Colors.blue,
            ),
            home: Scaffold(
                appBar: AppBar(
                    title: Text('helle world'),
                ),
                body: Container(
                        margin: EdgeInsets.symmetric(vertical: 48, horizontal: 24),
                        child: Navigator(
                        onGenerateRoute: (settings) {
                            return MaterialPageRoute<dynamic>(
                                settings: settings,
                                builder: (context) {
                                return Text('helle world');
                            });
                        },
                        onUnknownRoute: (settings) {
                            return MaterialPageRoute<dynamic>(
                                settings: settings,
                                builder: (context) {
                                return Text('helle world');
                            });
                        },
                        initialRoute: "home",
                    ),
                ),
            ),
        );
    }
}

If i use Text('hello') to replace Navigator, it works goods. Is it a bug in flutrer?

like image 526
lext Avatar asked Nov 24 '18 11:11

lext


People also ask

How do you add a shadow to a widget in Flutter?

Step 1: Add the Container widget. Step 2: Add the decoration parameter (inside Container) and assign the BoxDecoration class. Step 3: Add the boxShadow parameter (inside BoxDecoration) and assign the BoxShadow class. Step 4: Add the blurRadius parameter (inside BoxShadow) and set the value to 25.

What does Navigator POP do in Flutter?

By using the Navigator. pop() method. The pop() method removes the current Route from the stack of routes managed by the Navigator .


1 Answers

MaterialPageRoute is not a Material Widget itself. This shadow only occurs on iOS and is coming from the buildPageTransitions method in CupertinoPageRoute class....

When using a MaterialPageRoute Flutter looks at your pageTransitionsTheme and by default on iOS returns a CupertinoPageRouteTransitionsBuilder and Android a FadeUpwardsPageTransitionsBuilder

The shadow is part of iOS' default page transition but there might be good reasons why one doesn't want these to show up.

See: https://api.flutter.dev/flutter/material/PageTransitionsTheme-class.html https://raw.githubusercontent.com/flutter/flutter/master/packages/flutter/lib/src/cupertino/route.dart

There are a couple of solutions:


(1) Using a custom PageRouteBuilder (and building your own transitions) as suggested earlier works but it will break the default "swipe back" gesture on iOS that is implemented in CupertinoPageRoute.

(2) Define FadeUpwardsPageTransitionsBuilder as the default transition on iOS also. But again this will break the swipe back gesture on iOS.

MaterialApp(
  theme: ThemeData(
    pageTransitionsTheme: PageTransitionsTheme(
      builders: {
        TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),
        TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
      }
    ),
  ),
  ...
)

(3) Subclass CupertinoPageTransition and override build. Inside the build function there is an animation _primaryShadowAnimation that you don't need. This will keep the swipe back gesture on iOS intact. You would also have to subclass some parent classes such as CupertinoPageRouteTransitionsBuilder to return your custom CupertinoPageTransition instead So instead of:

# file: packages/flutter/lib/src/cupertino/route.dart, lines: 407-410
child: DecoratedBoxTransition(
  decoration: _primaryShadowAnimation,
  child: child,
),

you return child directly:

child: child,
like image 109
reinder Avatar answered Sep 18 '22 11:09

reinder