![](/img/trans.png)
[英]How to Make Custom AppBar in Flutter Like in Hamilton flutter app?
[英]How to make an appbar universal in your flutter app
我在我的 flutter 应用程序中创建了一个AppBar
,但我想让它通用(即我希望在我的应用程序的大多数屏幕中使用相同的AppBar
)。 我用一个名为AppBarscreen
的StatefulWidget
创建了一个新的 dart 文件,然后我返回了一个AppBar
小部件。 当我尝试调用另一个文件中的小部件时,出现如下错误:
[![我下面有这些红线][1]][1]
这是我创建的AppBarscreen
class 的代码:
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),
],
),
),
);
}
}
这是我调用AppBarscreen
小部件的屏幕代码:
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,
),
]),
),
),
),
);
}
}
请问我该如何摆脱错误?
为它制作一个方法,您可以在每个屏幕示例代码中使用它。
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),
],
),
),
);
}
无论您在appBar
中放置什么,都需要实现PreferredSizeWidget
。
例如,您可以更改AppBarScreen
以使其工作
class AppBarScreen extends StatefulWidget implements PreferredSizeWidget {
const AppBarScreen({super.key});
@override
State<AppBarScreen> createState() => _AppBarScreenState();
Size get preferredSize => Size.fromHeight(70);
}
如何在 Flutter 中将我的 AppBar 放在单独的文件中,同时仍然显示小部件?
因此,在您的可重用应用栏 class 实现实现 PreferredSizeWidget 并覆盖
@override Size get preferredSize => new Size.fromHeight(appBar.preferredSize.height);
然后你就可以访问了。
这是 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),
],
),
),
));
}
}
这适用于您要使用 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,
),
]),
),
),
),
);
}
}
创建一个将在其中实现 AppBar 的 ParentContainer。 就像下面的代码
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);
}
}
并将此 class 称为每个 class 中的顶部小部件。 喜欢
Widget build(BuildContext context) {
return ParentContainer(
title: "Discounts",
isShowLeading: true,
body:ListView()
...
....
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.