简体   繁体   中英

How to make an appbar universal in your flutter app

I created an AppBar in my flutter app but I want to make it universal (ie I want the same AppBar in most screens of my app). I created a new dart file with a StatefulWidget I called AppBarscreen , I then returned an AppBar widget. When I tried to call the widget in the other file I got an error like so:

[![I got these red lines under it][1]][1]

This is the code to the AppBarscreen class I created:

import 'package:flutter/material.dart';

class AppBarScreen extends StatefulWidget {
  const AppBarScreen({super.key});

  @override
  State<AppBarScreen> createState() => _AppBarScreenState();
}

class _AppBarScreenState extends State<AppBarScreen> {
  final GlobalKey<ScaffoldState> scaffoldkey = new GlobalKey<ScaffoldState>();
  @override
  Widget build(BuildContext context) {
    return AppBar(
      iconTheme: IconThemeData(color: Colors.black),
      toolbarHeight: 70,
      elevation: 0.0,
      backgroundColor: Color(0xFFE5E5E5),
      actions: [
        SizedBox(
          width: 10,
        ),
        Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Container(
                height: 50,
                width: 80,

          ],
        ),
        SizedBox(
          width: 90,
        ),
        Image.asset(
          "lib/assets/activity.png",
          height: 30,
          width: 30,
        ),
        SizedBox(
          width: 15,
        ),
        Image.asset(
          "lib/assets/notification-bing.png",
          height: 30,
          width: 30,
        ),
        SizedBox(
          width: 10,
        ),
        CircleAvatar(
          child: Icon(
            Icons.person,
            color: Colors.grey,
          ),
          backgroundColor: Colors.grey[300],
        ),
        SizedBox(
          width: 10,
        ),
      ],
      leadingWidth: 100,
      leading: GestureDetector(
        onTap: () => scaffoldkey.currentState!.openDrawer(),
        child: Row(
          children: [
            SizedBox(width: 20),
            Icon(Icons.menu, color: Colors.black),
          ],
        ),
      ),
    );
  }
}

And this is the code to the screen where I called the AppBarscreen widget:


import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';


class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
final GlobalKey<ScaffoldState> scaffoldkey = new GlobalKey<ScaffoldState>();
  final user = FirebaseAuth.instance.currentUser;

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        key: scaffoldkey,
        drawer: SideMenu(),
        backgroundColor: Color(0xFFE5E5E5),
        appBar: AppBarScreen(),
        body: Padding(
          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
          child: SingleChildScrollView(
            child:
                Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    "Dashboard",
                    style: TextStyle(fontSize: 35, letterSpacing: 0.2),
                  ),
                  Container(
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(8, 10, 15, 10),
                      child: Icon(
                        Icons.history,
                        size: 30,
                        color: Colors.green,
                      ),
                    ),
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.green, width: 2),
                      borderRadius: BorderRadius.circular(10),
                    ),
                  )
                ],
              ),
              Row(
                children: [
                  Text(
                    "How are you today?",
                    style: TextStyle(fontSize: 18),
                  ),
                  Image.asset(
                    "lib/assets/goodbye.png",
                    height: 20,
                  ),
                ],
              ),
              SizedBox(
                height: 10,
              ),
              Container(
                height: 140,
                child: PageView(
                  scrollDirection: Axis.horizontal,
                  children: [
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                        title: "Revenue",
                        rate: 0,
                        icon: "lib/assets/moneyrounded.png",
                        balance: 0,
                        color: Colors.green,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                          title: "Total Orders",
                          rate: 0,
                          icon: "lib/assets/clipboard2.png",
                          balance: 0,
                          color: Colors.blue),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                          title: "Total Products",
                          rate: 0,
                          icon: "lib/assets/box.png",
                          balance: 0,
                          color: Colors.orange),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: 30,
              ),
              //sales info card
              SalesInfo(),
              SizedBox(
                height: 50,
              ),
              //product info card
              ProductInfo(),
              SizedBox(
                height: 50,
              ),

              //expiry info card
              ExpiryInfo(),
              SizedBox(
                height: 50,
              ),

              //transaction card
              TransactionsCard(),
              SizedBox(
                height: 30,
              ),
            ]),
          ),
        ),
      ),
    );
  }
}


Please how do I get rid of the error?

make a method for it and you can use it in every screen sample code.

 AppBar newMethod() {
return AppBar(
  iconTheme: IconThemeData(color: Colors.black),
  toolbarHeight: 70,
  elevation: 0.0,
  backgroundColor: Color(0xFFE5E5E5),
  actions: [
    SizedBox(
      width: 10,
    ),
    Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Container(
            height: 50,
            width: 80,
            child: Image.asset("lib/assets/custigrow.png")),
      ],
    ),
    SizedBox(
      width: 90,
    ),
    Image.asset(
      "lib/assets/activity.png",
      height: 30,
      width: 30,
    ),
    SizedBox(
      width: 15,
    ),
    Image.asset(
      "lib/assets/notification-bing.png",
      height: 30,
      width: 30,
    ),
    SizedBox(
      width: 10,
    ),
    CircleAvatar(
      child: Icon(
        Icons.person,
        color: Colors.grey,
      ),
      backgroundColor: Colors.grey[300],
    ),
    SizedBox(
      width: 10,
    ),
  ],
  leadingWidth: 100,
  leading: GestureDetector(
    onTap: () => scaffoldkey.currentState!.openDrawer(),
    child: Row(
      children: [
        SizedBox(width: 20),
        Icon(Icons.menu, color: Colors.black),
      ],
    ),
  ),
);
}

Whatever you put in appBar needs to implement PreferredSizeWidget .

You can change your AppBarScreen for example to make it work

class AppBarScreen extends StatefulWidget implements PreferredSizeWidget {
  const AppBarScreen({super.key});

  @override
  State<AppBarScreen> createState() => _AppBarScreenState();

  Size get preferredSize => Size.fromHeight(70);
}

How can I have my AppBar in a separate file in Flutter while still having the Widgets show?

So on your reusable app bar class implements implements PreferredSizeWidget and override the

@override Size get preferredSize => new Size.fromHeight(appBar.preferredSize.height);

then you can able to access.

This is complete code for AppbarScreeen:

 import 'package:flutter/material.dart';
    
    class AppBarScreen extends StatefulWidget {
      const AppBarScreen({super.key});
    
      @override
      State<AppBarScreen> createState() => _AppBarScreenState();
    }
    
    class _AppBarScreenState extends State<AppBarScreen> {
      final GlobalKey<ScaffoldState> scaffoldkey = new GlobalKey<ScaffoldState>();
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
          iconTheme: IconThemeData(color: Colors.black),
          toolbarHeight: 70,
          elevation: 0.0,
          backgroundColor: Color(0xFFE5E5E5),
          actions: [
            SizedBox(
              width: 10,
            ),
            Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Container(
                    height: 50,
                    width: 80,
                    child: Image.asset("lib/assets/custigrow.png")),
              ],
            ),
            SizedBox(
              width: 90,
            ),
            Image.asset(
              "lib/assets/activity.png",
              height: 30,
              width: 30,
            ),
            SizedBox(
              width: 15,
            ),
            Image.asset(
              "lib/assets/notification-bing.png",
              height: 30,
              width: 30,
            ),
            SizedBox(
              width: 10,
            ),
            CircleAvatar(
              child: Icon(
                Icons.person,
                color: Colors.grey,
              ),
              backgroundColor: Colors.grey[300],
            ),
            SizedBox(
              width: 10,
            ),
          ],
          leadingWidth: 100,
          leading: GestureDetector(
            onTap: () => scaffoldkey.currentState!.openDrawer(),
            child: Row(
              children: [
                SizedBox(width: 20),
                Icon(Icons.menu, color: Colors.black),
              ],
            ),
          ),
        ));
      }
    }

And this is for where you want to use appbarscreen class

import 'package:custigrow/Utilities/app_bar.dart';
import 'package:custigrow/Utilities/expiry_information_card.dart';
import 'package:custigrow/Utilities/my_cards.dart';
import 'package:custigrow/Utilities/product_information_card.dart';
import 'package:custigrow/Utilities/sales_information_card.dart';
import 'package:custigrow/Utilities/transactions_card.dart';
import 'package:custigrow/screens/authenticate/sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:custigrow/Utilities/side_menu.dart';

class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
final GlobalKey<ScaffoldState> scaffoldkey = new GlobalKey<ScaffoldState>();
  final user = FirebaseAuth.instance.currentUser;

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        key: scaffoldkey,
        drawer: SideMenu(),
        backgroundColor: Color(0xFFE5E5E5),
         appBar: PreferredSize(
              preferredSize: Size.fromHeight(120), child: AppBarScreen()),
        body: Padding(
          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
          child: SingleChildScrollView(
            child:
                Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    "Dashboard",
                    style: TextStyle(fontSize: 35, letterSpacing: 0.2),
                  ),
                  Container(
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(8, 10, 15, 10),
                      child: Icon(
                        Icons.history,
                        size: 30,
                        color: Colors.green,
                      ),
                    ),
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.green, width: 2),
                      borderRadius: BorderRadius.circular(10),
                    ),
                  )
                ],
              ),
              Row(
                children: [
                  Text(
                    "How are you today?",
                    style: TextStyle(fontSize: 18),
                  ),
                  Image.asset(
                    "lib/assets/goodbye.png",
                    height: 20,
                  ),
                ],
              ),
              SizedBox(
                height: 10,
              ),
              Container(
                height: 140,
                child: PageView(
                  scrollDirection: Axis.horizontal,
                  children: [
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                        title: "Revenue",
                        rate: 0,
                        icon: "lib/assets/moneyrounded.png",
                        balance: 0,
                        color: Colors.green,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                          title: "Total Orders",
                          rate: 0,
                          icon: "lib/assets/clipboard2.png",
                          balance: 0,
                          color: Colors.blue),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 5),
                      child: MyCards(
                          title: "Total Products",
                          rate: 0,
                          icon: "lib/assets/box.png",
                          balance: 0,
                          color: Colors.orange),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: 30,
              ),
              //sales info card
              SalesInfo(),
              SizedBox(
                height: 50,
              ),
              //product info card
              ProductInfo(),
              SizedBox(
                height: 50,
              ),

              //expiry info card
              ExpiryInfo(),
              SizedBox(
                height: 50,
              ),

              //transaction card
              TransactionsCard(),
              SizedBox(
                height: 30,
              ),
            ]),
          ),
        ),
      ),
    );
  }
}

Make a ParentContainer where the AppBar will be implemented. Like below code

class ParentContainer extends StatelessWidget {
  final bool isShowLeading;
  final String title;
  final String toolTip;
  final Widget action;
  final VoidCallback callback;
  final Function onAction;
  final Widget body;
  final int walletBalance;

  ParentContainer({
    this.title,
    this.action,
    this.onAction,
    this.toolTip,
    this.callback,
    this.walletBalance,
    this.isShowLeading = false,
    @required this.body,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        // key: _scaffoldKey,
        resizeToAvoidBottomInset: false,
        backgroundColor: AppColor.appWhite,
        appBar: AppBar(
          elevation: 0,
          toolbarHeight: 0,
          leading: new IconButton(
            icon: new Icon(
              Icons.arrow_back,
              color: AppColor.appBrightBlue,
            ),
            onPressed: () => Navigator.of(context).pop(),
          ),
          title: Text(
            title != null ? title : "",
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(
                fontSize: 20,
                color: AppColor.appBrightBlue,
                fontWeight: FontWeight.bold),
          ),
          backgroundColor: AppColor.appPrimaryColor,
          centerTitle: false,
          actions: <Widget>[action != null ? action : Container()],
        ),
        body: body);
  }
}

And call this class as top widget in every class. like

Widget build(BuildContext context) {
 return ParentContainer(
  title: "Discounts",
  isShowLeading: true,
  body:ListView()
   ...
   ....
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM