yoohoo
yoohoo

Reputation: 1217

Navigating to another page from drawer menu and setting title to app bar

i am new to flutter and would like someone to help me with code i found in github that i would like to use. take a look at the link below https://github.com/JohannesMilke/drawer_example

this is an example of a navigational drawer. i like the way the developer coded it and would like to use this example. the problem is that the developer didnt implement navigating to another page. when you click on item in the drawer, it just print a message in the console.

i want to take this a step further. i want to modified the code so that when you click on a item it will navigate to another page and the drawer will b closed. the drawer icon should remain on the toolbar on the new page displayed. also, when you navigate to another page the title of that page should be set in the toolbar.

when i looked at the code , i have an idea where to change but i am not successful. i think i need to change the body tag at the bottom of the code. the problem is that i dont know how to call the DrawerWidgetState class in drawer_widget.dart file.


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

class MyApp extends StatelessWidget {
  final String appTitle =  'Ttitle';
  @override
  Widget build(BuildContext context) => MaterialApp(
    title: appTitle,
    theme: ThemeData(
      primaryColor: Colors.red,
      textTheme: TextTheme(
        subhead: TextStyle(
          color: Colors.black.withOpacity(0.4),
        ),
      ),
      dividerColor: Colors.black.withOpacity(0.4),
    ),
    home: MainPage(appTitle: appTitle),
  );
}

class MainPage extends StatefulWidget {
  final String appTitle;

  const MainPage({this.appTitle});

  @override
  MainPageState createState() => MainPageState();
}

class MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(
      title: Text(widget.appTitle),
    ),
    drawer: DrawerWidget(),
    body: container()
  );
}

i define the following function in drawer_widget.dart file

getDrawerItemWidget(int pos) {
    print('testing');
    switch (pos) {
      case 0:
        return new FirstFragment();
      case 1:
        return new SecondFragment();
      case 2:
        return new ThirdFragment();

      default:
        return new Text("Error");
    }
  }

but i dont know how to call it from Mainpage Body tag and set title accordingly. can someone help modify the code so that i can nagivate to another page and set title? full code is in https://github.com/JohannesMilke/drawer_example

thanks in advance

Upvotes: 5

Views: 5521

Answers (2)

Mariano Zorrilla
Mariano Zorrilla

Reputation: 7676

Using the drawer_example library you need to make some small changes in order to make it work.

Over your drawer_widget.dart add this add the beginning:

typedef TitleCallback = void Function(String, int);

Once you do that, your Drawer StatefulWidget should looks this way:

class DrawerWidget extends StatefulWidget {

  final TitleCallback callback;
  final int tabIndex;

  @override
  DrawerWidgetState createState() => DrawerWidgetState();

  DrawerWidget(this.callback, this.tabIndex);
}

and your initState:

@override
void initState() {
    selectedDrawerIndex = widget.tabIndex;
    selectedProfileIndex = 0;
    super.initState();
}

This will be the constructor to pass the new value back to your main.dart file.

Inside the ListTile, you can add the following logic:

ListTile(
     leading: Icon(item.icon),
     title: Text(item.name),
     selected: selectedDrawerIndex == currentIndex,
     onTap: () {
         final item = getOffsetIndex(drawerGroups, currentIndex);
         print('Selected index $selectedDrawerIndex with name ${item.name}');

         setState(() {
            selectedDrawerIndex = currentIndex;
            widget.callback(item.name, selectedDrawerIndex);
         });
         Navigator.pop(context); // to close the Drawer
     },
)

If you can check, the line: widget.callback(item.name); sends the tab name over the callback and that logic can be applied any where you want to change your title. It can even be a hard coded title like:

widget.callback("Second Tab");

Now, going back to your main.dart file:

class MyApp extends StatefulWidget {
    final String title;

    ListExample(this.title);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

   List<Widget> _fragments = <Widget> [
       Container(
         child: Text("Fragment One"),
       ),
       Container(
         child: Text("Fragment Two"),
       ),
       Container(
         child: Text("Fragment Three"),
       ),
   ];

  String titleAppBar = "Testing";
  int tabIndex = 0;

  @override
  void initState() {
    setState(() {
      titleAppBar = widget.title;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: widget.title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(titleAppBar),
        ),
        drawer: DrawerWidget((title, index) {
          setState(() {
            titleAppBar = title;
            tabIndex = index;
          });
        }, tabIndex),
        body: _fragments[tabIndex],
      ),
    );
  }
}

Final Result:

Drawer Flutter

Upvotes: 3

user10481267
user10481267

Reputation:

Looking at the example on GitHub, it's overcomplicating something that's too easy with Flutter.

Here's a simple example on how to use a Drawer on Flutter:

main.dart

import 'package:flutter/material.dart';

import 'another_page.dart';
import 'home_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // declaring your routes will allow you to push and remove everything from the stack (including the drawer) with pushNamedAndRemoveUntil()
      routes: {
        'home': (context) => HomePage(),
        'anotherPage': (context) => AnotherPage(),
      },
      initialRoute: 'home',
    );
  }
}

home_page.dart (another_page.dart is exactly the same for illustration purpose)

import 'package:flutter/material.dart';

import 'menu_drawer.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: MenuDrawer(),
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Text('Home'),
      ),
    );
  }
}

menu_drawer.dart

import 'package:flutter/material.dart';

class MenuDrawer extends StatelessWidget {

  // Push the page and remove everything else
  navigateToPage(BuildContext context, String page) {
    Navigator.of(context).pushNamedAndRemoveUntil(page, (Route<dynamic> route) => false);
  }

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        // This could be mapped from a List of items
        children: <Widget>[
          ListTile(
            leading: Icon(Icons.home),
            title: Text('Home'),
            onTap: () => navigateToPage(context, 'home'),
          ),
          ListTile(
            leading: Icon(Icons.panorama),
            title: Text('Another page'),
            onTap: () => navigateToPage(context, 'anotherPage'),
          ),
        ],
      ),
    );
  }
}

Final result:

enter image description here

Upvotes: 3

Related Questions