0

Let's say I have a base page in a Material App. The basepage only has one widget, a scaffold. The scaffold contains an appbar, that is to remain constant through the app, in every page. The scaffold also contains a body, which should be overriden by the pages that extend the base to display their contents.

How can I go about to do this? Thanks for the help!

CJSZ
  • 41
  • 2
  • 6

3 Answers3

1

You could create a globally accessible page like this:

base_page.dart
import 'package:flutter/material.dart';

class BasePage extends StatelessWidget {
  /// Body of [BasePage]
  final Widget body;

  const BasePage({@required this.body, Key key})
      : assert(body != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          // Your appbar content here
          ),
      body: body,
    );
  }
}

And when you want to use it, just provide the body to the new class like this:

main.dart
import 'package:flutter/material.dart';
import 'base_page.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BasePage(
      // This is where you give you custom widget it's data.
      body: Center(child: Text('Hello, World')),
    );
  }
}
Apealed
  • 1,415
  • 8
  • 29
  • Thanks! I think the original answer asked for a way to "extend" some type of "base page" and this isn't exactly using that technique. This is traditional Flutter Widget re-usage and design pattern that is more approachable to more Flutter developers. Still seems like an appropriate answer to the question. – Apealed Mar 02 '21 at 16:18
0

One way to do this is to create a variable holding the current route in your StatefulWidget.

Widget currentBody = your initial body ; 

and then change that variable whenever you want to switch the body using setState:

SetState(() { currentBody = your new body widget }) ;      

and in your scaffold after the appbar you put !

 body : currentBody ; 
Amine Dakhli
  • 142
  • 8
  • Interesting idea, I'm new to flutter so I still struggle with the whole state -> widget concept, but I'm going to research more about this approach, it seems very versatile. Thank you! – CJSZ Mar 02 '21 at 15:22
0

You have many ways to do this, one is to use the Bloc package, but another way is to use a Bottom Navigation Bar](https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html)

The bottom navigation bar consists of multiple items in the form of text labels, icons, or both, laid out on top of a piece of material. It provides quick navigation between the top-level views of an app. For larger screens, side navigation may be a better fit.

A bottom navigation bar is usually used in conjunction with a Scaffold, where it is provided as the Scaffold.bottomNavigationBar argument.

I provided an example in my answer for transparent appbar, of course you do not need your appbar to be transparent.

class HomePageState extends State<Homepage> {
    List<Widget> widgets = [Text("haha"), Placeholder(), Text("hoho")]; // as many widgets as you have buttons.
    Widget currentWidget = widgets[0];
    void _onItemTapped(int index) {
        setState(() {
            NavigationBar._selectedIndex = index;
            currentWidget = widgets[index];
        });
    }

    @override
    Widget build(BuildContext context) {

        return return MaterialApp(
                home: Scaffold(
                    extendBody: true, // very important as noted
                    bottomNavigationBar: BottomNavigationBar(
                         currentIndex: NavigationBar._selectedIndex,
                         selectedItemColor: Colors.amber[800],
                         onTap: _onItemTapped,
                         backgroundColor: Color(0x00ffffff), // transparent
                         type: BottomNavigationBarType.fixed,
                         unselectedItemColor: Colors.blue,
                         items: const <BottomNavigationBarItem>[
                             BottomNavigationBarItem(
                                 icon: Icon(Icons.home),
                                 title: Text('Home'),
                             ),
                             BottomNavigationBarItem(
                                 icon: Icon(Icons.grade),
                                 title: Text('Level'),
                             ),
                                 [...] // remaining in the link 
                    ),
                    body: Container(
                        decoration: BoxDecoration(
                            image: DecorationImage(
                                image: ExactAssetImage("assets/background.png"), // because if you want a transparent navigation bar I assume that you have either a background image or a background color.
                                fit: BoxFit.fill
                            ),
                        ),
                        child: currentWidget
                    ),
                ),
            );
        }
    }
                ...

The Bloc architecture is harder to understand, you will need to read documentation and try tutorials, but it is also very interesting to implement.

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
  • Ah, of course, I forgot about the bottom bar, it's a good idea as well. And about this bloc architecture, it's completely new to me. I certainly will look it up as go for some tutorials about it, thanks for the suggestion! – CJSZ Mar 02 '21 at 15:24