Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter 2.0 appbar back button disappeared if contains endDrawer

Tags:

flutter

I just updated flutter to 2.0, and I realized all the back buttons disappeared if the appbar also conatains an endDrawer

Appbar with endDrawer

I tried to get rid of the endDrawer, the back button shows up, just not together with the endDrawer, it wasn't like that before the update, anybody knows how to solve this?

Appbar without endDrawer

my code:

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(),
    );
  }
}
like image 488
qwea Avatar asked Mar 05 '21 01:03

qwea


People also ask

How can I add back button in Flutter without AppBar?

Just WRAP your widget into a Stack and then add an IconButton on top of the Stack and Navigator. pop(context) on button onPressed(). That should solve your problem.

How do I change the back button icon in AppBar Flutter?

Step 1: Inside the AppBar , add the leading parameter and assign the BackButton widget. Step 2: Inside the BackButton, add the color parameter and assign the color of your choice.


Video Answer


2 Answers

This is current behavior in version 2.0, if condition also check !hasEndDrawer
version 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

version 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

You can add your own logic in leading
code snippet

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'),
      ),

working demo

enter image description here

full code

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(),
    );
  }
}
like image 109
chunhunghan Avatar answered Dec 04 '22 15:12

chunhunghan


Just add this to your AppBar/SliverAppBar

      leading: (ModalRoute.of(context)?.canPop ?? false) ? BackButton() : null,
like image 39
Abdul Rahman Avatar answered Dec 04 '22 15:12

Abdul Rahman