为什么嵌套导航器之间存在阴影?

时间:2018-11-24 11:44:15

标签: flutter

当我使用嵌套在包含导航器的MaterialApp中的导航器时,会出现阴影,如下图所示。

为什么?如何消除阴影?

enter image description 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",
                    ),
                ),
            ),
        );
    }
}

如果我使用Text('hello')来代替Navigator,那么它将起作用。这是Flutrer中的错误吗?

4 个答案:

答案 0 :(得分:0)

MaterialPageRoute本身是一个材质小部件,因此它具有高程和阴影。

请改用PageRouteBuilder,这是不包含实际效果的页面路由。一个很好的例子是Navigator文档的“自定义路线”部分。

编辑:抱歉,文档中的示例似乎不适合您的情况。您可以像这样使用PageRouteBuilder

Navigator(
    //...
    onGeneratedRoute: PageRouteBuilder(
        pageBuilder: //...
        transitionsBuilder: //There are some good examples about this transition animation on the web
    ),
    //...
)

答案 1 :(得分:0)

MaterialPageRoute本身不是Material Widget。此阴影仅发生在iOS上,并且来自buildPageTransitions类中的CupertinoPageRoute方法。...

使用MaterialPageRoute时,Flutter会查看您的pageTransitionsTheme,默认情况下,iOS上会返回CupertinoPageRouteTransitionsBuilder,而Android会返回FadeUpwardsPageTransitionsBuilder

阴影是iOS默认页面转换的一部分,但可能有充分的理由使人们不希望这些阴影出现。

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

有两种解决方案:


(1)如先前建议的那样使用自定义PageRouteBuilder(并构建自己的过渡),但是它将破坏在CupertinoPageRoute中实现的iOS上默认的“向后滑动”手势。

(2)还将FadeUpwardsPageTransitionsBuilder定义为iOS上的默认过渡。但这又会破坏iOS上的向后滑动手势。

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

(3)子类CupertinoPageTransition并覆盖build。在构建函数内部,有不需要的动画_primaryShadowAnimation。这将使iOS上的向后滑动手势保持原样。您还必须继承某些父类,例如CupertinoPageRouteTransitionsBuilder,以返回自定义CupertinoPageTransition 所以代替:

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

您直接将孩子送还

child: child,

答案 2 :(得分:0)

我想我找到了一个可行的解决方案:

转到flutter\packages\flutter\lib\src\cupertino\route.dart

更改这部分(应该是第 789 行):

static DecorationTween kTween = DecorationTween(
    begin: const _CupertinoEdgeShadowDecoration._(), // No decoration initially.
    end: const _CupertinoEdgeShadowDecoration._(
      // Eyeballed gradient used to mimic a drop shadow on the start side only.
      <Color>[
        Color(0x38000000),
        Color(0x12000000),
        Color(0x04000000),
        Color(0x00000000),
      ],
    ),
  );

为此:

static DecorationTween kTween = DecorationTween(
    begin: const _CupertinoEdgeShadowDecoration._(), // No decoration initially.
    end: const _CupertinoEdgeShadowDecoration._(
      // Eyeballed gradient used to mimic a drop shadow on the start side only.
      <Color>[
        Color(0x00FFFFFF),
        Color(0x00FFFFFF),
      ],
    ),
  );

它的作用是:将默认阴影颜色替换为透明。

答案 3 :(得分:-1)

您可以将导航器包裹在ClipRect中。

return ClipRect(child:Navigator(