如果包含 endDrawer,Flutter 2.0 appbar 后退按钮会消失

Posted

技术标签:

【中文标题】如果包含 endDrawer,Flutter 2.0 appbar 后退按钮会消失【英文标题】:Flutter 2.0 appbar back button disappeared if contains endDrawer 【发布时间】:2021-06-03 17:01:58 【问题描述】:

我刚刚将flutter更新到2.0,我意识到如果appbar也包含一个endDrawer,所有的后退按钮都会消失

Appbar with endDrawer

我试过去掉endDrawer,后退按钮出现了,只是没有和endDrawer一起,更新前不是这样的,有人知道怎么解决吗?

Appbar without endDrawer

我的代码:

import 'package:flutter/material.dart';

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

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


class Page1 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Container(
        child: Center(
            child: TextButton(
          child: Text(
            'Page 1',
            style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
          ),
          onPressed: () 
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => Page2()));
          ,
        )),
      ),
    );
  


class Page2 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Container(
        child: Center(
          child: TextButton(
          child: Text(
            'Page 2',
            style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
          ),
          onPressed: () 
            Navigator.pop(context);
          ,
        ),
        ),
      ),
      endDrawer: Drawer(),
    );
  

【问题讨论】:

【参考方案1】:

只需将此添加到您的 AppBar/SliverAppBar

      leading: (ModalRoute.of(context)?.canPop ?? false) ? BackButton() : null,

【讨论】:

【参考方案2】:

这是 2.0 版中的当前行为,if 条件还检查!hasEndDrawer 1.17版

if (canPop)
          leading = useCloseButton ? const CloseButton() : const BackButton();

https://github.com/flutter/flutter/blob/aee9e94c21009bfc6c08f442eacde06f001c25f9/packages/flutter/lib/src/material/app_bar.dart#L510

2.0 版

if (!hasEndDrawer && canPop)
      leading = useCloseButton ? const CloseButton() : const BackButton();

https://github.com/flutter/flutter/blob/ca2bef6ee915d943b5a160055b5065ec3391f19a/packages/flutter/lib/src/material/app_bar.dart#L793

您可以在leading 中添加自己的逻辑 代码sn-p

appBar: AppBar(
        leading: Builder(
          builder: (BuildContext context) 
            final ScaffoldState scaffold = Scaffold.maybeOf(context);
            final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);
            final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
            final bool canPop = parentRoute?.canPop ?? false;

            if (hasEndDrawer && canPop) 
              return BackButton();
             else 
              return SizedBox.shrink();
            
          ,
        ),
        title: Text('Page 2'),
      ),

工作演示

完整代码

import 'package:flutter/material.dart';

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

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


class Page1 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Container(
        child: Center(
            child: TextButton(
          child: Text(
            'Page 1',
            style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
          ),
          onPressed: () 
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => Page2()));
          ,
        )),
      ),
    );
  


class Page2 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        leading: Builder(
          builder: (BuildContext context) 
            final ScaffoldState scaffold = Scaffold.maybeOf(context);
            final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);
            final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
            final bool canPop = parentRoute?.canPop ?? false;

            if (hasEndDrawer && canPop) 
              return BackButton();
             else 
              return SizedBox.shrink();
            
          ,
        ),
        title: Text('Page 2'),
      ),
      body: Container(
        child: Center(
          child: TextButton(
            child: Text(
              'Page 2',
              style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
            ),
            onPressed: () 
              Navigator.pop(context);
            ,
          ),
        ),
      ),
      endDrawer: Drawer(),
    );
  

【讨论】:

以上是关于如果包含 endDrawer,Flutter 2.0 appbar 后退按钮会消失的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 的 appbar 之外添加 endDrawer?

Flutter之抽屉组件drawer,设置drawer宽度——Flutter基础系列

d2d1debug3.dll!DebugRenderTarget::EndDraw 访问冲突

如果我包含某个包,Flutter android 应用程序在启动时崩溃

检查数组是不是包含另一个数组及其在 DART/Flutter 中的位置

扑。镖。 Flutter - 替换列表中的项目